I noticed something in C# when dealing with custom objects that I found to be a little odd. I am certain it is just a lack of understanding on my part so maybe someone can enlighten me.
If I create a custom object and then I assign that object to the property of another object and the second object modifies the object assigned to it, those changes are reflected in the same class that did the assigning even though nothing is returned.
You want that in English? Here is an example:
class MyProgram
{
static void Main()
{
var myList = new List<string>();
myList.Add("I was added from MyProgram.Main().");
var myObject = new SomeObject();
myObject.MyList = myList;
myObject.DoSomething();
foreach (string s in myList)
Console.WriteLine(s); // This displays both strings.
}
}
public class SomeObject
{
public List<string> MyList { get; set; }
public void DoSomething()
{
this.MyList.Add("I was added from SomeObject.DoSomething()");
}
}
In the above sample I would have thought that, because SomeObject.DoSomething() returns void, this program would only display "I was added from MyProgram.Main().". However, the List<string> in fact contains both that line and "I was added from SomeObject.DoSomething()".
Here is another example. In this example the string remains unchanged. What is the difference and what am I missing?
class MyProgram
{
static void Main()
{
var myString = "I was set in MyProgram.Main()";
var myObject = new SomeObject();
myObject.MyString = myString;
myObject.DoSomething();
Console.WriteLine(myString); // Displays original string.
}
}
public class SomeObject
{
public string MyString { get; set; }
public void DoSomething()
{
this.MyString = "I was set in SomeObject.DoSomething().";
}
}
This program sample ends up displaying "I was set in MyProgram.Main()". After seeing the results of the first sample I would have assumed that the second program would have overwritten the string with "I was set in SomeObject.DoSomething().". I think I must be misunderstanding something.
This isn’t odd, or strange. When you create a class, you create reference type. When you pass references to objects around, modifications to the objects they refer to are visible to anyone that holds a reference to that object.
So in this block of code, you instantiate a new instance of
List<string>and assign a reference to that instance to the variablemyList. Then you add"I was added from MyProgram.Main()."to the list referred to bymyList. Then you assign a refernce to that same list tomyObject.MyList(to be explicit, bothmyListandmyObject.MyListare referring to the sameList<string>! Then you invokemyObject.DoSomething()which adds"I was added from SomeObject.DoSomething()"tomyObject.MyList. Since bothmyListandmyObject.MyListare referring to the sameList<string>, they will both see this modification.Let’s go by way of analogy. I have a piece of paper with a telephone number on it. I photocopy that piece of paper and give it to you. We both have a piece of paper with the same telephone number on it. Now I call up that number and tell the person on the other end of the line to put a banner up on their house that says
"I was added from MyProgram.Main()."You call up the person on the other end of the line to put a banner up on their house that says"I was added from SomeObject.DoSomething()". Well, the person who lives at the house that has that telephone number is now going to have two banners outside their house. One that saysand another that says
Make sense?
Now, in your second example, it’s a little trickier.
You start by creating a new
stringwhose value is"I was set in MyProgram.Main()"and assign a reference to that string tomyString. Then you assign a reference to that same string tomyObject.MyString. Again, bothmyStringandmyObject.MyStringare referring to that samestringwhose value is"I was set in MyProgram.Main()". But then you invokemyObject.DoSomethingwhich has this interesting lineWell, now you’ve created a new
stringwhose value is"I was set in SomeObject.DoSomething()."and assign a reference to thatstringtomyObject.MyString. Note that you never changed the reference thatmyStringholds. So now,myStringandmyObject.MyStringare referring to different strings!Let’s go by analogy again. I have a piece of paper with a web address on it. I photocopy that piece of paper and give it to you. We both have a piece of paper with the same web address on it. You cross out that web address and write down a different address. It doesn’t affect what I see on my piece of paper!
Finally, a lot of people in this thread are yammering about the immutability of
string. What is going on here has nothing to do with the immutability ofstring.