In the following line:
List<T> exampleList = new List<T>(toModify)
you create a list of T calling List<T>
's constructor that takes one argument of type IEnumerable<T>
. For further info on the latter, please have a look here.
Method's arguments in C# are passed by default by value and not by reference. They can be passed by reference, but you have to explicitly state this in the signature of the corresponding method using the ref
keyword and at the point you call this method, using again the same keyword. So the toModify
is passed by value to the constructor of List<T>
.
What's the importance of this?
In C# types can be divided into two categories (despite the fact that all types inherit from the System.Object):
- Value types
- Reference types
When we pass a value type as an argument, we pass a copy of it's value. Each modification we make in either the original value or in the copy of the original value is not reflected to one another. On the other hand, when we pass a reference type as an argument, we pass a copy of that reference. So now we have two references (pointers) that point to the same location in memory. That being said, it's clear that if we change any property of the object in which both references points to, this would be visible by both of them.
In your case, this is what is happening. toModify
is a list of reference types (under the hood you have an array, whose items are references to other objects). So any change to the items of the initial list, toModify
, is reflected to the list you construct based on this list.
A simple example that you could use to verify the above is the following:
public class Point
{
public int X { get; set; }
public int Y { get; set; }
public override string ToString() => $"X: {X}, Y: {Y}";
}
class Program
{
static void Main(string[] args)
{
var listA = new List<int> {1, 2, 3};
var listB = new List<int>(listA);
// Before the modification
Console.WriteLine(listA[0]); // prints 1
Console.WriteLine(listB[0]); // prints 1
listA[0] = 2;
// After the mofication
Console.WriteLine(listA[0]); // prints 2
Console.WriteLine(listB[0]); // prints 1
Console.ReadKey();
var pointsA = new List<Point>
{
new Point {X = 3, Y = 4},
new Point {X = 4, Y = 5},
new Point {X = 6, Y = 8},
};
var pointsB = new List<Point>(pointsA);
// Before the modification
Console.WriteLine(pointsA[0]); // prints X: 3, Y: 4
Console.WriteLine(pointsB[0]); // prints X: 3, Y: 4
pointsA[0].X = 4;
pointsA[0].Y = 3;
// After the modification
Console.WriteLine(pointsA[0]); // prints X: 4, Y: 3
Console.WriteLine(pointsB[0]); // prints X: 4, Y: 3
Console.ReadKey();
}
}