2011-01-12 9 views
9

Ich habe ein Problem mit List<T>.Reverse() und Reverse(this IEnumerable<TSource> source). Blick auf den Code:Warum funktioniert IList <>. Reverse() nicht wie List <>(). Reverse

// Part 1 
    List<int> list = new List<int> { 1, 2, 3 }; 

    foreach (int x in list) 
    Console.Write(x); 

    Console.WriteLine(); 

    list.Reverse(); 

    foreach (int x in list) 
    Console.Write(x); 

    Console.WriteLine(); 
    list.Reverse(); 

    // Part2 
    IList<int> ilist = list; 

    foreach (int x in list) 
    Console.Write(x);  

    Console.WriteLine(); 

    ilist.Reverse(); 

    foreach (int x in ilist) 
    Console.Write(x); 

    Console.WriteLine(); 

    ilist.Reverse(); 

Mein Ergebnis:

123 
321 
123 
123 

weil Reverse() -Part1 List<T>.Reverse() ist, Reverse() -Part2 ist Reverse(this IEnumerable<TSource> source) I List<int>.Reverse() in Teil2 für IList<int> ausgeführt werden soll. Wie kann ich es tun?

+2

sagen [Ich stimme Ihnen zu, dass dies verwirrend.] (Http://stackoverflow.com/questions/2828917/most- peinlich-irreführende-Methode-in-the-net-api/2829051 # 2829051) –

Antwort

8

hat keine Reverse Methode, so dass es die Erweiterungsmethode verwendet. Die einzige Möglichkeit, List<T>.Reverse auf Ihrer Referenz zu verwenden, besteht darin, sie in eine List<int> zu konvertieren. Casting funktioniert nur, wenn Sie sicher sind, dass es wirklich ein List<int> an erster Stelle:

IList<int> abstractList; 
var concreteList = (List<int>)abstractList; 
concreteList.Reverse(); 

Eine weitere Option ein List<int> von Ihrer IList<int> Instanz erstellen würde, anstatt es bereits unter der Annahme ist ein List<int>:

IList<int> abstractList; 
var concreteList = new List<int>(abstractList); 
concreteList.Reverse(); 

der Grund, dass die Reverse Extension-Methode tatsächlich nicht die zugrunde liegende Liste beeinflussen, weil sie auf IEnumerable<T> arbeiten, w hich ist nicht unbedingt beschreibbar (keine der Erweiterungsmethoden Enumerable nimmt Änderungen an der ursprünglichen Sammlung vor, sie geben eine neue Sammlung zurück).

Um diese Version von Reverse, benutzen Sie einfach das Produkt der Reverse Anruf zu verwenden, statt der ursprünglichen Liste:

IList<int> abstractList; 
IEnumerable<int> reversedList = abstractList.Reverse(); 
4

Im zweiten Beispiel, sind Sie eine Erweiterungsmethode gegen IEnumerable<T> verwenden und diese Die ursprüngliche Sammlung wird nicht mutiert, sondern es wird eine Abfrage erzeugt, die zu einer Reihenfolge der ursprünglichen Liste in umgekehrter Reihenfolge führt. Das heißt, wenn Sie die Ergebnisse von ilist.Reverse() nutzen wollen, würden Sie

var reversedList = iList.Reverse(); 
// reversedList is IEnumerable<int> 
// 'list' and 'ilist' are not changed 

foreach (int item in reversedList) 
    Console.Write(item); 
+0

kurze, aber knappe Antwort auf das Problem zur Hand. Hat mir geholfen. Danke +1 –

Verwandte Themen