In der folgenden Zeile:
List<T> exampleList = new List<T>(toModify)
erstellen Sie eine Liste von T List<T>
‚s Konstruktor aufrufen, die IEnumerable<T>
ein Argument vom Typ nimmt. Weitere Informationen zu letzterem finden Sie unter .
Die Argumente der Methode in C# werden standardmäßig nach Wert und nicht per Referenz übergeben. Sie können als Referenz übergeben werden, aber Sie müssen dies explizit in der Signatur der entsprechenden Methode angeben, indem Sie das Schlüsselwort ref
verwenden und an dem Punkt, an dem Sie diese Methode aufrufen, erneut dasselbe Schlüsselwort verwenden. So wird der toModify
Wert an den Konstruktor List<T>
übergeben.
Was ist das wichtig?
In C# Typen können (trotz der Tatsache, dass alle Arten von System.Object erben) in zwei Kategorien unterteilt werden:
Wenn wir passieren ein Werttyp als Argument übergeben wir eine Kopie des Wertes. Jede Änderung, die wir entweder im ursprünglichen Wert oder in der Kopie des ursprünglichen Werts vornehmen, wird nicht zueinander widergespiegelt. Auf der anderen Seite, wenn wir einen Referenztyp als Argument übergeben, übergeben wir eine Kopie dieser Referenz. Jetzt haben wir zwei Referenzen (Zeiger), die auf den gleichen Ort im Speicher zeigen. Wenn wir jedoch eine Eigenschaft des Objekts ändern, auf die beide Referenzen zeigen, ist dies für beide sichtbar.
In Ihrem Fall ist dies, was passiert.toModify
ist eine Liste von Referenztypen (unter der Haube haben Sie ein Array, dessen Elemente Verweise auf andere Objekte sind). Jede Änderung an den Elementen der ursprünglichen Liste, toModify
, spiegelt sich in der Liste wider, die Sie anhand dieser Liste erstellen.
Ein einfaches Beispiel, dass Sie die oben zu überprüfen, verwenden könnte, ist die folgende:
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();
}
}
Das Verhalten von C# ist genau dasselbe wie das Verhalten von Java in dieser Hinsicht. Können Sie erklären, was Sie meinen, wenn Sie sagen, dass Sie die Liste "modifizieren"? Stellen Sie vielleicht ein minimales Codebeispiel zur Verfügung, um das Verhalten zu zeigen, das Sie sehen? – StriplingWarrior
[C# Konzepte: Wert gegen Referenztypen] (http://www.albahari.com/valuevsreftypes.aspx) –