Klassen sind reference Typen, Strukturen sind value Typen.
Wenn ein value -Typ als Parameter an eine Methode übergeben wird, wird eine Kopie davon übergeben. Das bedeutet, dass Sie zwei vollständig separate Kopien der Struktur Person
hinzufügen, eine für jeden Durchlauf in der Schleife.
Wenn ein Verweis -Typ als Parameter an eine Methode übergeben wird, wird die Referenz übergeben. Das bedeutet, dass Sie zwei Kopien der Referenz zum selben Speicherort hinzufügen (zum selben Person
-Objekt) - wenn Sie Änderungen an diesem einen Objekt vornehmen, sehen Sie es in beiden Referenzen reflektiert, da beide referenziere das gleiche Objekt.
Es ist der Unterschied zwischen Werttyp (struct) und Referenztyp (Klasse).
Wenn Sie die Struktur zu Listperson
hinzufügen, wird der Inhalt der Person in die Liste eingefügt. Sie haben zwei verschiedene Personenstrukturen in Ihrer Liste.
Wenn Sie die Klasse hinzufügen, in der die Referenz in die Liste eingefügt wird, haben Sie zwei Referenzen, die auf dasselbe Personenobjekt verweisen.
%Vor%Weil Ihre myperson-Variable immer nur eine Person struct / class behandelt.
Was Sie der Liste in Ihrer Schleife hinzufügen, ist eine Kopie Ihrer myperson -Variablen - die für die Struktur eine vollständige Kopie der Struktur ist, für die Klasse jedoch eine Kopie der -Referenz für die einzelne Instanz, die Sie erstellen (und mutieren).
Wenn Sie dasselbe Ergebnis wollen, dann bringen Sie die Deklaration der Person in die for-Schleife: -
%Vor%In struct fügt man einen Werttyp hinzu, daher werden separate Werte gespeichert, während man in der Klasse einen Verweis auf das Objekt hinzufügt und daher den gleichen Wert erhält.
In der zweiten Instanz fügen Sie einen Referenztyp hinzu. In der Tat fügen Sie das gleiche Element zweimal hinzu, seit Ihrem
%Vor%ist nicht in der Schleife. Es zeigt also immer auf das gleiche Objekt, das Sie hier initialisiert haben:
%Vor%Auch nachdem es zu Ihrer Liste hinzugefügt wurde, wirken sich die Änderungen darauf aus.
In der ersten Instanz fügen Sie jedes Mal eine Struktur hinzu, bei der es sich um einen Werttyp handelt, der also in die Liste kopiert wird. Änderungen, die Sie danach vornehmen, beziehen sich nicht mehr auf das Objekt in der Liste, daher haben sie unterschiedliche Werte.
Strukturen sind Werttypen und Klassen sind Referenztypen. In Ihrem ersten Beispiel, wenn Sie myperson zur Liste hinzufügen, bezieht sich das Hinzufügen einer Kopie von myperson und der Variable myperson immer noch auf eine separate Kopie. In Ihrem zweiten Beispiel ist myperson ein Referenztyp, also fügen Sie zwei Zeiger zu demselben Objekt hinzu.
Sie sollten Schlüsselunterscheidungen zwischen Strukturen ( Wertetypen ) und Klassen (< a href="http://msdn.microsoft.com/en-us/library/490f96s2.aspx"> Referenztyp ). Sie können diese Informationen leicht in Google oder SO .
Wenn Sie struct instance zu List hinzufügen, erstellen Sie eine weitere separate Kopie für diese Instanz, und wenn Sie ein Element ändern, haben Sie kein anderes geändert.
Aber im Fall von Klassen erstellen Sie eine Instanz und verwenden diese "gemeinsame" Instanz mit zwei Referenzen (Liste [0] und Liste 1 ) und Sie könnten diese eine Instanz durch zwei verschiedene Referenzen ändern, deshalb scheint es, wenn Sie das Listenelement [0] ändern, dass Sie die Liste ändern 1 Element auch.
Betrachten Sie folgenden Code:
%Vor%Ähnliches Verhalten haben wir, wenn wir Parameter an Funktion übergeben (oder Element zur Liste hinzufügen).
Im zweiten Beispiel erstellen Sie nur ein Element und fügen einen Verweis auf die Liste mehrmals hinzu.
Wenn Sie die Struktur zur Sammlung hinzufügen, erstellt sie eine Kopie davon. Es ist ein -Werttyp . Sie erhalten zwei unterschiedliche Objekte in der Sammlung mit jeweils unterschiedlichen Werten. Dies ist wahrscheinlich das erwartete Verhalten.
Wenn Sie die Klasse, den Verweistyp , zur Sammlung hinzufügen, wird kein neues Objekt erstellt. Sie fügen dem gleichen Objekt zwei verschiedene Referenzen hinzu. Sie erhalten (scheinbar) zwei Objekte mit demselben Wert. Es ist eigentlich das gleiche Objekt, scheinbar zweimal in der Sammlung.
Denken Sie an Variablen und Parameter von Klassentypen, die eine "Instanz-ID" enthalten. Die einzigen Dinge, die man direkt mit einer Instanz-ID tun kann, sind (1) Erstellen einer neuen (die einer neuen Instanz einer Klasse zugewiesen wird), (2) Zuweisen einer anderen oder (3) Überprüfen von zwei IDs Schau, ob sie gleich sind. Alles andere mit einer Variablen, einem Parameter usw. eines Klassentyps ist eine kurze Hand für "do _ für die Instanz, die auf diese Instanz-ID verweist".
Also Code wie:
%Vor%Die erste "neue" Anweisung wird eine Instanz von Car erstellen und ihre Instanz-ID (sagen wir # 1234) in "A" setzen. Die zweite wird eine andere Auto-Instanz erstellen (# 4321) und ihre ID in B speichern. Die nächste Anweisung wird # 1234 in C kopieren. Es macht nichts mit dem Auto - es kopiert nur die ID. Dann wird das Auto # 1234 gelb gestrichen, dann wird in der letzten Aussage die Farbe des Autos # 1234 (d. H. Gelb) verwendet, um das Auto # 4321 zu malen. Beachten Sie, dass, während A und C unterschiedliche Variablen sind, beide die gleiche Instanz-ID (# 1234) haben und sich somit auf dasselbe Auto beziehen.