tags:

views:

590

answers:

7

I have something similar to this:

// Declarations:
List<SomeType> list1 = new List<SomeType>();
List<SomeType> list2 = new List<SomeType>();

...

SomeType something = new SomeType("SomeName");
list1.Add(something);
list2.Add(something);

...

list1[indexOfSomething] = new SomeType("SomeOtherName");

And the object in list2 isn't changed... Is that the expected result?

+2  A: 

Yes, you're not cloning the object. The object is being added to both lists originally by reference, and then subsequently you're assigned a reference in the list to the new object you're creating.

That is definitely the expected result.

Joseph
+2  A: 

You are not cloning the object; you are adding a reference to the same object in the two lists. However, your code replaces the reference in one of the lists with a reference to another object, so yes, this is the expected behaviour.

Fredrik Mörk
A: 

Yes that is expected. Only the reference to the object is added. Not the reference itself or a copy.

JaredPar
+11  A: 

Yes, but nothing's cloned. Before the assignment, the same object is in both lists. After the assignment, you have two unique objects in two lists.

Do This:

list1[indexOfSomething].name = "SomeOtherName";

and the object in list2 will change, too.

Can Berk Güder
Let's say SomeType is an interface and my goal is to update the object to a different class that inherits the interface (not the same code as above since you can't instantiate an interface - technicalities aside though), would the only way to go about the be to locate the object in both lists and replace them with the new object? Or is there some other clever way?
Berdon Magnus
The "clever" way would be to have some wrapper type that implements the interface and delegates to a member that implements the same interface. Put the wrapper in both lists, and then you can update the object that the wrapper holds in just one spot and both lists will get the update.
Eddie Deyo
+2  A: 

When you pass the 'something' object to Add you are passing by value (c# default), not by reference

Jon Erickson
I don't think this is correct. You're passing the reference by value, but you're still passing a reference. In the example, the assignment re-assigns the reference in list1 and that's why the reference in list2 is unchanged.
Jamie Ide
+4  A: 

You're replacing the reference in one list with a reference to a new object. If you were to instead change a property of that object, you would see it changed in both places, since the reference would remain the same.

Jon B
+2  A: 
// Declarations:
List<SomeType> list1 = new List<SomeType>();
List<SomeType> list2 = new List<SomeType>();

...

SomeType something = new SomeType("SomeName");
list1.Add(something);
list2.Add(something);

Remember, when you add an object to a list, you're really just adding a pointer to the object. In this case, list1 and list2 both point to the same address in memory.

list1[indexOfSomething] = new SomeType("SomeOtherName");

Now you've assigned the element list1 to a different pointer.

You're not really cloning objects themselves, you're copying the pointers which just happen to be pointing at the same object. If you need proof, do the following:

SomeType something = new SomeType("SomeName");
list1.Add(something);
list2.Add(something);

list1[someIndex].SomeProperty = "Kitty";

bool areEqual = list1[someIndex].SomeProperty == list2[someIndex].SomeProperty;

areEqual should be true. Pointers rock!

Juliet