C# Question

They both don’t get a copy of the string object. They both get their own copies of a reference to the string object.

The following code demonstrates that both tables contains reference to the same object, not copies of the object:

using System;
using System.Threading;
using System.Collections;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.FEZ;

namespace StringTester
{
    public class Program
    {
        public static void Main()
        {
            String ts = "This is the test string";
 
            // create the hashtables
            Hashtable table1 = new Hashtable();
            Hashtable table2 = new Hashtable();

            // put ts into both with key of zero
            table1[0] = ts;
            table2[0] = ts;

            if (table1[0] == table2[0])
                Debug.Print("Same string object");
            else
                Debug.Print("Different string object");

            Thread.Sleep(Timeout.Infinite);
        }
    }
}

The output is “Same string object”

Just tried this…

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            String ts1 = "This is the test string";
            String ts2 = "This is the test string";

            // create the hashtables
            Hashtable table1 = new Hashtable();
            Hashtable table2 = new Hashtable();

            // put ts into both with key of zero
            table1[0] = ts1;
            table2[0] = ts2;

            if (table1[0] == table2[0])
                Console.WriteLine("Same string object");
            else
                Console.WriteLine("Different string object");

            Console.ReadKey();

        }
    }
}

The output is “Same string object”

I think the table1[0] == table2[0] comparison is comparing the string value and not the object itself.

Interesting!

In Jas’s example I think they are the same because .Net will point both strings to the same char array in memory if the char arrays are equal in “value”, so the value that is being compared is the value of the reference (pointer). It will automatically create a different reference if one of the strings is modified:

string ts1 = "This is a test string";
string ts2 = "This is a test string";
ts1 == ts2 because .Net compares the values of strings by overriding the == operator.
ts1 = "This is a new string";
ts1 != ts2

I read this somewhere on MSDN, but can’t find the reference right now.

Correct.

@ Ian - is that true or is it comparing the reference values?

After playing around with

Object.ReferenceEquals(x,y)

“Determines whether the specified Object instances are the same instance.”

it still seems to point to it being the same instance.

The usually == is used to compare references, but in the String class == has been overloaded to compare the contents of the string.

@ Jas - So in your example do you think the comparison is on the value of the references, and not on the value of the strings?

Here’s a good article for explaining C# string comparisons.

Good article Ian.

So based on this:

I would say that in @ Jas’s second example the comparison was against the value of the references, and not on the value of the char arrays.

And also, because of the optimization that .Net tries to do with strings, I would say that this code:

string str1 = "Test string";
string str2 = "Test string";
string str3 = str1;
str1 == str2 is true because of string char comparison.
((object)str1) == ((object)str2) is true because .Net points the two references to the same char array.
((object)str1) == ((object)str3) is true because of reference comparison.

Do you agree?

I agree…but… You have to understand that this is not the same as C++. Although they reference the same pointer at the moment it’s really useless information because if you do this after your code…

   
         str1 = "Test";
         ((object)str1) == ((object)str3);            <== FALSE 

…because now str1 will point to a different memory location due to the immutable nature of C# strings.