2016-11-19 4 views
5

Ich habe ein kleines Problem, wenn ich einige Operationen in C# machen möchte. Ich werde dir ein kleines Beispiel geben.Stapel der generischen Liste wird gelöscht, wenn die gedrückte Liste gelöscht wird

In diesem Code möchte ich meine verknüpfte Liste auf einen Stapel schieben, als alle Elemente in der Liste entfernen. Wenn ich die Liste lösche, verschwindet der erste Index meines Stacks, weil er als Referenz übergeben wurde. Liege ich falsch? Weil ich nicht weiß, warum es passiert.

So verwende ich die Weitergabe nach Wert Methode.

Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>(); 
List<HufmannLetter> letterList = new List<HufmannLetter>(); 

while(true) { 

    letterList.Add("asd"); 
    letterList.Add("sad"); 

    List<HufmannLetter> tempLetterList = new List<HufmannLetter>(letterList); 
    steps.Push(tempLetterList); 
    letterlist.Clear();  
} 

Ist es ein guter Weg, um ein Problem zu lösen? So funktioniert es, aber die Lesbarkeit nimmt ab. Was schlägst du mir vor?

Dank ...

+2

"Bin ich falsch?" Ja, es gibt keinen Pass-by-Reference in dem Code, den Sie gezeigt haben. Man kann das an dem Fehlen von "ref" und "out" erkennen. Ich schlage vor, dass Sie http://jonskeet.uk/csharp/parameters.html und http://jonskeet.uk/csharp/references.html lesen. Beachten Sie, dass das Übergeben eines Verweises nach Wert nicht dasselbe ist wie beim Pass-by-Reference. –

Antwort

3

Erstellen Sie einfach ein neues List<HufmannLetter> Objekt innerhalb der Schleife und dass auf den Stapel hinzufügen. Die Wiederverwendung desselben Listenobjekts hat keine Leistungsvorteile.

Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>(); 

while(true) 
{ 
    List<HufmannLetter> letterList = new List<HufmannLetter>(); 

    letterList.Add("asd"); 
    letterList.Add("sad"); 

    steps.push(letterList); 
} 
+0

Ja, ich weiß, es wirkt sich nicht auf meine Leistung aus, aber ich denke über die Verständlichkeit meines Codes nach. Aber wenn es keinen Weg gibt, werde ich meinen Code nicht ändern. Vielen Dank :) – Berkin

+1

Keine der Antworten erklärt OP's 'Wenn ich die Liste lösche, verschwindet der erste Index meines Stacks, weil er als Referenz übergeben wurde. Liege ich falsch? Weil ich nicht weiß, warum es passiert. –

+0

@Berkin, was meinst du mit _ "es gibt keinen Weg" _? Mein Beispiel ist nicht identisch mit Ihrem. –

1

Sie können new List<HufmannLetter>() erstellen und die vorherige Liste im Konstruktor geben, wird dieses neue Objekt erstellen, die nicht gelöscht werden.

while(condition) 
{ 
    letterList.Add("asd"); 
    letterList.Add("sad"); 

    steps.push(new List<HufmannLetter>(letterList)); 
    letterlist.Clear(); 
} 

EDIT

So wird List<T> Referenztyp, setzen Sie die letterList im Stapel. Auf diese Weise übertragen Sie den Wert der Referenz List<T> in den Stapel Artikel. Die Variable lastList verweist also auf dasselbe Objekt wie das Element in Ihrem Stapel. Wenn Sie die Elemente aus der Briefliste löschen, werden sie auch im Stapelelement gelöscht.

prüfen, was Reference Types ist

+1

Keine der Antworten erklärt OP's 'Wenn ich die Liste lösche, verschwindet der erste Index meines Stacks, weil er als Referenz übergeben wurde. Liege ich falsch? Weil ich nicht weiß, warum es passiert. –

+0

@Am_I_Hilfful Ich denke, der Op versteht, warum die Werte aus seinen Listen im Stapel gelöscht werden. Wenn er es nicht versteht, werde ich eine kleine Erklärung schreiben. – mybirthname

-1

können Sie auch tun, dass als

Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>(); 

while(true) 
{ 
var tempList = new List<HufmannLetter>; 
tempList.add("asd"); 
steps.push(tempList); 
} 

oder können Sie versuchen, diese

steps.push(tempList.ToList()); 
    tempList.Clear(); 
+0

Dies ist die gleiche Antwort wie botond.botos, die vor 6 Minuten gegeben wurde. – mybirthname

+0

Ja, es ist aber bitte überprüfen Sie den zweiten Teil –

1

List<> ein veränderliches Referenztyp ist. Wenn Sie eine List<> an eine Methode übergeben, übergeben Sie eine Kopie von die Referenz. Also sag einfach, welche List<> es ist. Das wird den gesamten Inhalt der List<> nicht kopieren (klonen).

Wenn Sie setzen (Push) eine List<> auf dem Stack<>, was die Stack<> wirklich hält, ist eine Kopie eines Verweises auf diese Instanz von List<>. Wenn diese Instanz später geändert wird, zum Beispiel mit .Add("asd") oder mit .Clear(), wird diese "Mutation" angezeigt, unabhängig davon, ob Sie der Referenznummer Stack<> oder einer anderen Referenz aus der lokalen Variablen folgen. Beide Referenzen "zeigen" auf dieselbe Instanz von List<>.

Wenn in Ihrem Code, sagen Sie:

letterList.Clear(); // do not change reference, follow reference and mutate the instance it refers to 

, dass die vorhandene Instanz von List<> so wird es leer wird ändern (mutieren). Diese Änderung wird von jedem gesehen, der einen Verweis auf diese bestimmte Instanz von List<> hat.

Wenn stattdessen hatte man getan:

letterList = new List<string>(); // create new instance, change reference to point there (reference assignment), old instance is unchanged 

, die „bewegt“ die Referenz von letterList zu deuten auf eine neue Instanz List<> haben würde. Dies würde Personen mit anderen Verweisen auf die "alte" Instanz nicht betreffen.


Der Titel Pass von Referenznutzungs ist irreführend. Es sollte Referenztypen sein und Referenzen übergeben oder so ähnlich.

Verwandte Themen