0

I already knew that in C#, string are reference type that are handled mostly like a value type, but I recently discover this: http://net-informations.com/faq/general/immutable.htm

I'm trying to "prove" that string are immutable by printing the reference to a string variable anytime a concatenation occurs:

string s = string.Empty;
for (int i = 0; i < 10; i++)
{
    s += " " + i;
    // Console.WriteLine(&s);
}

As you can guess, the code doesn't compile if the line is uncommented (Compiler Error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('type')).

I also tried the GetHashCode(), but apparently for string it returns the same value based on the... String value itself (ie. it will always return the same result for "0" for instance).

Is there a way to do that? It won't be for a coding purpose, just for an understanding purpose... If not, how can you know that it will "really" create n instances of a string at each concatenation? Appart from "knowing it"...

EDIT: probably not a duplicate of C# memory address and variable, because I want to know how to get the address of a reference type, and apparently that thread deals only with value type.

Community
  • 1
  • 1
benichka
  • 925
  • 1
  • 11
  • 32

3 Answers3

2

If you want to check that a new instance was created, just compare it to the previous instance:

string s = string.Empty;
for (int i = 0; i < 10; i++)
{
    var saved = s;
    s += " " + i;
    if (ReferenceEquals(saved, s))
        Console.WriteLine("oops, no new instance created?");
}

You'll see that this won't print anything.

2

You can use the ObjectIDGenerator to generate ids for the strings and see if the ids are the same.

var string1 = "Jerry";
ObjectIDGenerator generator = new ObjectIDGenerator();
bool string1FirstTime;
long string1Id = generator.GetId(string1, out string1FirstTime);


bool string2FirstTime;
var string2 = string1 + " Seinfeld";
long string2Id = generator.GetId(string2, out string2FirstTime);

Below will return false because they are not the same.

var same = string1Id == string2Id;
CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
  • Instead of var string2 = string1 + " Seinfeld"; why not string1 += " Seinfeld"; ? And then obviously : long string2Id = generator.GetId(string1, out string2FirstTime); I tried it this way and the results are different -> string1 was re-instanciated. Thanks ! – benichka Feb 19 '17 at 19:38
  • @benichka because I wanted to keep it as simple as possible and concentrate on the answer to the given question. The `+=` will just be more code to digest and take away from the real focus. – CodingYoshi Feb 19 '17 at 20:03
1

You can copy the string to another variable, and compare their references and value before and after modification:

string s = string.Empty;
for (int i = 0; i < 10; i++)
{
    var copy = s;

    // true
    Console.WriteLine("both are the same reference: {0}", Object.ReferenceEquals(s, copy));
    // true
    Console.WriteLine("both are the same value: {0}", s.Equals(copy));

    s += " " + i;

    // false
    Console.WriteLine("both are the same reference: {0}", Object.ReferenceEquals(s, copy));
    // false
    Console.WriteLine("both are the same value: {0}", s.Equals(copy));
}
JLRishe
  • 99,490
  • 19
  • 131
  • 169