2013-07-31 22 views
7

Mam dwa pytania:Wewnętrzne Realizacja AsEnumerable() w LINQ

Pytanie 1 Wstęp: zauważyłem, kiedy patrząc na realizację 'AsEnumerable()' metoda w LINQ firmy Microsoft, który był:

public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source) 
{ 
    return source; 
} 

Pytanie 1: spodziewałem się jakiś casting czy coś, ale to po prostu zwraca wartość nie została podjęta. Jak to działa ?

Pytanie 2/3 Tło: staram się zrozumieć kowariancji kontrawariancji i niezmienne. Myślę, że mam niejasne zrozumienie, że słowa kluczowe "w" i "na zewnątrz" określają zachowanie polimorficzne podczas przypisywania podtypu do typu macierzystego.

Pytanie 2: wiem z lektury, że IEnumerable jest kowariantna, a lista jest niezmienna, to dlaczego jest to niemożliwe:

List<char> content = "testString".AsEnumerable(); 

Pytanie 3:
Jeśli IList implementuje IEnumerable dlaczego to nie jest możliwe:

IEnumerable<char> content1 = "testString"; 
IList<char> content2 = content1; 

Proszę mi pomóc zrozumieć, dziękuję w dvance.

+0

AsEnumerable() wymusza zapytanie do natychmiastowego wykonania w innych dostawcach LINQ, takich jak LINQ do SQL lub Entity Framework. Jest prawdopodobnie dodany do LINQ do Objects dla kompletności. –

Odpowiedz

3
  1. Argument wejściowy jest już znany jako typ IEnumerable<TSource>. Dlaczego miałby cokolwiek rzucać? Przesyłanie obiektów do typu TSource nie przyniosłoby efektu, ponieważ są już gwarantowane tego typu (lub bardziej pochodnego typu).

  2. Nie można przypisać wartości typu IEnumerable<char> do zmiennej typu List<char>. Myślę, że myślisz tutaj odwrotnie; List<char> wywodzi się z IEnumerable<char>, a nie na odwrót. Nie ma to nic wspólnego z List<T> będącym niezmiennikiem. IEnumerable<T> jest kowariantna (aby być bardziej precyzyjnym, parametr typ T jest kowariantna), co daje nam tę sytuację:

    IEnumerable enumerable = Enumerable.Empty<string>(); // Allowed 
    IEnumerable<string> genericEnumerable = enumerable; // Not allowed 
    
  3. znowu IList<char> dziedziczy IEnumerable<char>, a nie na odwrót. Możesz to zrobić:

    IList<char> content1 = "testString".ToList(); 
    IEnumerable<char> content2 = content1; 
    

    To, o co prosisz, nie ma sensu, obawiam się, i nie ma to nic wspólnego z kowariancją. Fakt, że IEnumerable<T> jest kowariantna oznacza, że ​​masz prawo to zrobić:

    IEnumerable<object> asObject = new List<string>() { "test" }; 
    

    Ale List<T> jest niezmienna, więc nie można tego zrobić:

    List<object> asObject = new List<string>() { "test" }; 
    
+0

Potrzebuję trochę czasu, aby to przetrawić! – RaM

+0

W odpowiedzi na pierwszą odpowiedź, rozumiem, więc jeśli mogę bezpośrednio przypisane wartości obiektu pochodnego do wystąpienia typu nadrzędnego, to w jakim celu rozwiązuje "AsEnumerable()"? – RaM

+0

W odpowiedzi na drugą odpowiedź, OK, dlaczego jest IEnumerable enumerable = (IEnumerable) Enumerable.Empty (); niemożliwe ? IEnumerable implementuje IEnumerable, więc dlaczego kompilator narzeka? – RaM