Reputation:
I've just seen this in the MS Visual Studio docs and the part in bold doesn't make sense to me. Is it wrong or am I not understanding it properly? If you run this, b appears to hold "hello" (as I would expect) and not "h".
Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this. For example, when you write this code, the compiler actually creates a new string object to hold the new sequence of characters, and the variable b continues to hold "h".
string b = "h";
b += "ello";
Upvotes: 4
Views: 589
Reputation: 81159
It would perhaps be clearest to regard all class-type storage locations as holding "object IDs". Suppose that, initially, the compiler has assigned ID #123
to the string "h" and has assigned ID #547
to the string "ello". Then after the statement b = "h";
, the variable b
will hold ID #123
. The statement b += "ello";
will cause the compiler to pass ID #123
and ID #547
to the +
operator for string, which will in turn pass them to the String.Concat
method. That method will in turn ask the system to create a new object (e.g. ID #915
) of type System.String
, holding the five characters "hello"
, and return that object to the caller. The compiler will then store ID #915
into b
.
Upvotes: 0
Reputation: 14995
The docs are wrong. The variable b now holds "hello". The string is immutable but the variable can be reassigned.
Upvotes: 4
Reputation: 64068
You've done an addition AND an assignment in one step. Strings are immutable, but also a reference type.
string b = "h";
b = b + "ello";
We can look at the pseudo-memory like this:
string b = "h"; // b := 0x00001000 ["h"]
string tmp1 = "ello"; // tmp1 := 0x00002000 ["ello"]
string tmp2 = b + tmp1; // tmp2 := 0x00003000 ["hello"]
string b = tmp2; // b := 0x00003000 ["hello"]
I'm not entirely sure where you're getting that text, because as I read the documentation for the string class I find (not that I think "h" actually gets garbage collected):
Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this. For example, when you write this code, the compiler actually creates a new string object to hold the new sequence of characters, and that new object is assigned to b. The string "h" is then eligible for garbage collection.
@Jon Skeet brings up that "h" will never be garbage collected due to string interning, and I agree with him, but even moreso the C# Standard agrees with him, otherwise the following from §2.4.4.5 String literals could not be true:
Each string literal does not necessarily result in a new string instance. When two or more string literals that are equivalent according to the string equality operator (§7.9.7) appear in the same program, these string literals refer to the same string instance.
Upvotes: 7
Reputation: 33474
Simply put, strings cannot be modified in place (if string is an array of characters)
Upvotes: 0
Reputation: 199225
Try this:
string b = "h";
string c = b + "ello"; // b still == "h", c = "hello"
string d = string.concat(b, "ello"); // d == hello, b still "h"
Why b is still "h" ? Because "b" is not an object, it is an object reference. There is nothing you can do to the object referenced by b to change it. If strings where mutable then using:
string b = "ello";
string f = b.Insert("h",0);
would modify b to "hello" ( because h was inserted at position 0 ) but as it is inmutable b remains "ello".
If you change the reference to other object that a different thing.
b = "ello";
b = "Some other string";
// b not references "Some other string" , but the object "ello" remains unchanged.
I hope it helps ( and works :S )
Upvotes: 0
Reputation: 4292
I don't know what C# does, but I did read about this in Java, and an implementation based on Java would be more like this:
string b = "h" ;
b = (new StringBuilder(b)).Append("ello").ToString() ;
The point is that the "+" or "Append" does not exist for string because string is immutable.
Upvotes: 0
Reputation: 48121
People don't seem to be understanding the question. No one is arguing that string objects aren't immutable. The point of contention is what he bolded:
and the variable b continues to hold "h"
I agree with the OP that this portion of the doc is incorrect on two counts:
(1) In the obvious intuitive sense that if you print(b) (or whatever the correct statement is in this language) after his two sample lines you will get "hello" as the result.
(2) In the strict sense that the variable b doesn't hold "h", "hello", or any string value. It holds a reference to a string object.
The contents of the variable b do change as a result of the assignment -- it changes from a point to string object "h" to a pointer to string object "hello".
When they say "hold" what they really mean is "points to". And they are wrong, after the assignment b no longer points to "h".
I think the example they really wanted to give is this:
string a = "h";
string b = a;
b += "ello";
The point being that a would, I believe, still point to "h"; i.e., the assignment to b doesn't modify the object it was pointing to, it creates a new object and changes b to point to it.
(I don't actually write C# but this is my understanding.)
Upvotes: 5
Reputation: 29009
The misunderstanding here is about reference types:
String is a reference type, not a value type. This means, your variable b is not an object of type string, it is a reference to an object of type string in memory.
What the doc says, is that the object in memory is immutable.
Still, your reference to the object can be changed to point to some other (immutable) object in memory.
For you it might look like the content of the object has changed, but in the memory it has not, and this is all that immutable thingy is about.
The string itself is immutable. What your example changed was not the string class in memory, but the reference your variable is pointing to.
See this slightly modified code:
string b = "h";
string m1 = b;
b += "ello";
// now b == "hello", m1 == "h"
In the end b will point to "hello", while m1 will point to "h". For you it might seem like "h" has changed to "hello", but it has not. b+="ello" created a new string class containing "hello" and assigned it to b, while the old b still is present in Memory and still contains "b".
If string was not immutable, m1 would contain "hello", too, instead of just "b", because both b and m1 pointed to the same reference.
Upvotes: 4
Reputation: 3417
What's happening is that you're making a new variable that holds 'hello', and then changing b to reference this, the memory for the 'old' b still contains 'h', but that's no longer needed so the garbage collector will clean it up. This is why it's so good to use stringbuilders when iterating and sticking strings together - see this for more info.
Upvotes: 0
Reputation: 76008
string b = "h"; b += "ello";
b is just a reference to object in heap. Actually, after the "+=" operation, b doesn't reference to the original "h" any more. Now, it reference to a new string object "hello" which is concatenation of "h" and "ello". The "h" string will be collected by GC.
Upvotes: 0
Reputation: 103505
A string cannot change, but a string variable can be assigned a different value. What you are doing is closer to :
string b = "h";
string temp = b + "ello";
b = temp;
To show the actual immutablity of string, this will fail:
string b="hello";
if(b[0] == 'h') // we can read via indexer
b[0] = 'H'; // but this will fail.
Upvotes: 2
Reputation: 1500535
Yes, the docs are wrong. (The docs for a number of string methods imply mutability too. They're basically poorly written.)
Heck, even the use of "the compiler" creating the new string object is off. Basically it's doing:
string b = "h";
b = string.Concat(b, "ello");
At that point the compiler's job is done - it's the framework which creates the new string object.
Upvotes: 4
Reputation: 49482
There are now three strings. One is the original "h", one is "ello" and the third is "hello". Your b variable points to the "hello" string. The other two strings have no references to them and can be thrown away up by the garbage collector.
Upvotes: 1