2011-01-12 22 views
9

Mam problem z List<T>.Reverse() i Reverse(this IEnumerable<TSource> source). Spójrz na kod:Dlaczego funkcja IList <>. Reverse() nie działa tak jak Lista <>(). Odwróć

// 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(); 

Mój wynik:

123 
321 
123 
123 

ponieważ Reverse() -Part1 jest List<T>.Reverse(), Reverse() -Part2 jest Reverse(this IEnumerable<TSource> source) Chcę wykonać List<int>.Reverse() w part2 dla IList<int>. Jak mogę to zrobić?

+2

[Zgadzam się z Tobą, że jest to mylące.] (Http://stackoverflow.com/questions/2828917/most- niezręczna-myląca-metoda-w-sieci-api/2829051 # 2829051) –

Odpowiedz

8

IList<int> nie ma metody Reverse, więc używa metody rozszerzenia. Jedynym sposobem użycia numeru List<T>.Reverse na twoim numerze referencyjnym IList<int> jest przesłanie lub przekonwertowanie go na List<int>. Casting będzie działać tylko wtedy, gdy jesteś pewien, że to naprawdę List<int> w pierwszej kolejności:

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

Innym rozwiązaniem byłoby tworzyć się List<int> z wystąpieniem IList<int> zamiast zakładając, że już jest List<int>:

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

powodem że metoda Reverse przedłużenie faktycznie nie wpływa na listę podstawową jest, ponieważ działa na IEnumerable<T>, w hich niekoniecznie jest zapisywalny (żadna z metod rozszerzenia Enumerable nie wprowadza zmian w oryginalnej kolekcji, zwracają one nową kolekcję).

Aby korzystać z tej wersji Reverse, wystarczy użyć produkt zaproszenia Reverse zamiast oryginalnej listy:

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

w drugim przykładzie, używasz metodę rozszerzenia przeciwko IEnumerable<T>, a to nie modyfikuje oryginalnej kolekcji, ale raczej tworzy zapytanie, które spowoduje sekwencję oryginalnej listy w odwrotnej kolejności. To znaczy, jeśli chcesz wykorzystać wyniki ilist.Reverse(), można by powiedzieć

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

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

krótką, ale zwięzłą odpowiedź na dany problem. Pomógł mi. Dziękujemy +1 –

Powiązane problemy