-4

In the code below, changes on cpy value does not affect ori value, so string does not behave like a reference type :

string ori = "text 1";
string cpy = ori;
cpy = "text 2";
Console.WriteLine("{0}", ori);

but, a class has a different behaviour :

class WebPage
{
    public string Text;
}

// Now look at reference type behaviour
WebPage originalWebPage = new WebPage();
originalWebPage.Text = "Original web text";

// Copy just the URL
WebPage copyOfWebPage = originalWebPage;

// Change the page via the new copy of the URL
copyOfWebPage.Text = "Changed web text";

// Write out the contents of the page
// Output=Changed web text
Console.WriteLine ("originalWebPage={0}",
                           originalWebPage.Text);

can someone tell me why the behaviour is different between a class and string while the two of them are reference types ?

Alex K.
  • 171,639
  • 30
  • 264
  • 288
Hicham
  • 983
  • 6
  • 17
  • Strings are immutable and can't be changed – Saggio Dec 15 '14 at 14:33
  • the best thing i can say is to lookup how reference types work. – Daniel A. White Dec 15 '14 at 14:33
  • 5
    Actually, no, a class does *not* have a different behaviour. You are just doing two different things in your example: For strings, you assign a new value (`"text 2"`) to the `string` variable `cpy` itself. For your class `WebPage`, you just assign a new value (`"Changed web text"`) to a *property* (`Text`) of (the instance referenced by) your variable `copyOfWebPage`. – O. R. Mapper Dec 15 '14 at 14:34
  • 1
    In this line `cpy = "text 2";` you are changing the string that variable `cpy` references. In this line `copyOfWebPage.Text = "Changed web text";` you are not changing the object that `copyOfWebPage` references, you are changing the property `Text`, of the object referenced by both variables. – Ben Robinson Dec 15 '14 at 14:34
  • more info on string immutability: http://stackoverflow.com/questions/2365272/why-net-string-is-immutable – DLeh Dec 15 '14 at 14:34
  • 1
    @DLeh Irrelevant to the question though. What this question has to do with immutability ? – Sriram Sakthivel Dec 15 '14 at 14:37
  • @SriramSakthivel strings "not acting like reference types" is a consequence of them being immutable. – DLeh Dec 15 '14 at 14:37
  • 2
    @SriramSakthivel: nothing, but all fall into the same trap. – Tim Schmelter Dec 15 '14 at 14:38
  • 1
    @DLeh Forget about string. Even if you use `StringBuilder` you'll see the same output. because OP is modifying the reference with new instance, not mutating it(which is not possible with string). – Sriram Sakthivel Dec 15 '14 at 14:39
  • no need to downvote ! the first answer is fine. i didnt know that behaviour. It is different than the c++ that I know more. – Hicham Dec 15 '14 at 14:50
  • @HichamfromCppDependTeam C++ acts exactly the same too. – Scott Chamberlain Dec 15 '14 at 15:49
  • @ScottChamberlain no c++ does not act the same. string is not immutable and it is not a reference type. the = operator is used to copy the content of the string litteral to the string. (in : string str = "abc").So there is no reference behaviour in cpy = ori. the content of ori is simply copied to cpy. cpy is not a reference to the same data in c++. – Hicham Dec 16 '14 at 10:17

2 Answers2

5

Even though strings are immutable this situation has nothing to do with that. When you assign a new reference to a reference type, you are throwing away the old one. In your second example, you are changing a property of your object, since they are pointing to same location, both of them are affected.

But when you do

cpy = "text 2";

It means create a new string and store it's reference into cpy and throw away the old reference of cpy.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
2

Classes behave exactly like strings, you are just not doing the same thing in your two examples.

WebPage originalWebPage = new WebPage();
originalWebPage.Text = "Original web text";    

WebPage copyOfWebPage = originalWebPage;

//Overwrite the copy variable just like you did before
copyOfWebPage = new WebPage();
copyOfWebPage.Text = "Modified web text";

Console.WriteLine ("originalWebPage={0}", originalWebPage.Text);
Console.WriteLine ("copyOfWebPage={0}", copyOfWebPage.Text);

Run this example

The classes example makes it more obvious what is going on, when you did

string cpy = ori;
cpy = "text 2";

you copied the text of ori in to cpy, you then immedatly threw away that value an copied "text 2" in to cpy, you never actually "modified" the value of the object cpy refers to, you just made it point to a new object.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431