Initially, it can be represented graphically as follow:
Then, the sort is applied myList.Sort();
Finally, when you did: myList' = myList2
, you lost the one of the reference but not the original and the collection stayed sorted.
If you use by reference (ref
) then myList'
and myList
will become the same (only one reference).
Note: I use myList'
to represent the parameter that you use in ChangeList
(because you gave the same name as the original)
You are passing a reference to the list, but your aren't passing the list variable by reference - so when you call ChangeList
the value of the variable (i.e. the reference - think "pointer") is copied - and changes to the value of the parameter inside ChangeList
aren't seen by TestMethod
.
try:
private void ChangeList(ref List<int> myList) {...}
...
ChangeList(ref myList);
This then passes a reference to the local-variable myRef
(as declared in TestMethod
); now, if you reassign the parameter inside ChangeList
you are also reassigning the variable inside TestMethod
.
Here is an easy way to understand it
Your List is an object created on heap. The variable myList
is a
reference to that object.
In C# you never pass objects, you pass their references by value.
When you access the list object via the passed reference in
ChangeList
(while sorting, for example) the original list is changed.
The assignment on the ChangeList
method is made to the value of the reference, hence no changes are done to the original list (still on the heap but not referenced on the method variable anymore).
This link will help you in understanding pass by reference in C#. Basically,when an object of reference type is passed by value to an method, only methods which are available on that object can modify the contents of object.
For example List.sort() method changes List contents but if you assign some other object to same variable, that assignment is local to that method. That is why myList remains unchanged.
If we pass object of reference type by using ref keyword then we can assign some other object to same variable and that changes entire object itself.
(Edit: this is the updated version of the documentation linked above.)
C# just does a shallow copy when it passes by value unless the object in question executes ICloneable
(which apparently the List
class does not).
What this means is that it copies the List
itself, but the references to the objects inside the list remain the same; that is, the pointers continue to reference the same objects as the original List
.
If you change the values of the things your new List
references, you change the original List
also (since it is referencing the same objects). However, you then change what myList
references entirely, to a new List
, and now only the original List
is referencing those integers.
Read the Passing Reference-Type Parameters section from this MSDN article on "Passing Parameters" for more information.
"How do I Clone a Generic List in C#" from StackOverflow talks about how to make a deep copy of a List.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With