2013-07-31 12 views
7

Ich habe zwei Fragen:interne Implementierung von AsEnumerable() in LINQ

Frage 1 Hintergrund: Ich habe bemerkt, wenn sie bei der Umsetzung von 'AsEnumerable()' Methode in LINQ von Microsoft sucht, das war:

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

Frage 1: ich war eine Art Casting oder etwas hier erwartet, aber es gibt einfach den Wert, den es übergeben wurde. Wie funktioniert das ?

Frage 2/3 Hintergrund: Ich habe versucht, Covariance, Kontravarianz und Invariant zu verstehen. Ich denke, ich habe ein vages Verständnis, dass "in" - und "out" -Schlüsselwörter das polymorphe Verhalten bestimmen, wenn Sie einem Elterntyp einen Subtyp zuweisen.

Frage 2: Ich weiß aus der Lektüre, dass IEnumerable ist covariant und Liste ist unveränderlich, warum dann ist dies nicht möglich:

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

Frage 3:
Wenn IList IEnumerable implementiert, warum dann ist das nicht möglich:

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

Bitte helfen Sie mir zu verstehen, danke in einem Dvance.

+0

AsEnumerable() zwingt die Abfrage, die sofort in anderen LINQ-Providern wie LINQ to SQL oder Entity Framework ausgeführt wird. Es wurde wahrscheinlich LINQ to Objects zur Vollständigkeit hinzugefügt. –

Antwort

3
  1. Das Eingabeargument ist bereits bekannt IEnumerable<TSource> den Typ haben. Warum sollte es etwas werfen? Das Umsetzen der Objekte auf den Typ TSource hätte keine Auswirkung, da sie garantiert bereits von diesem Typ (oder einem abgeleiteten Typ) sind.

  2. Sie können keinen Wert vom Typ IEnumerable<char> auf eine Variable vom Typ List<char> zuweisen. Ich denke du denkst hier umgekehrt; List<char> stammt von IEnumerable<char>, nicht umgekehrt. Dies hat nichts damit zu tun, dass List<T> invariant ist. IEnumerable<T> kovariant (genauer zu sein, der Typparameter T kovariant), die uns diese Situation gibt:

    IEnumerable enumerable = Enumerable.Empty<string>(); // Allowed 
    IEnumerable<string> genericEnumerable = enumerable; // Not allowed 
    
  3. Wieder IList<char> erbt von IEnumerable<char>, nicht umgekehrt. Sie können dies tun:

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

    Was Sie fragen, macht keinen Sinn, ich habe Angst, und es hat nichts mit Kovarianz zu tun. Die Tatsache, dass IEnumerable<T> ist covariant bedeutet, dass Sie dies tun dürfen:

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

    Aber List<T> ist unveränderlich, so dass Sie dies nicht tun können:

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

Ich brauche etwas Zeit, um das zu verdauen! – RaM

+0

Als Antwort auf die erste Antwort verstehe ich, also, wenn ich einen Wert des abgeleiteten Objekts direkt einer Instanz des übergeordneten Typs zuweisen kann, welchen Zweck löst 'AsEnumerable()'? – RaM

+0

Als Antwort auf die zweite Antwort, OK, also warum ist IEnumerable enumerable = (IEnumerable) Enumerable.Empty (); nicht möglich ? IEnumerable Implementiert IEnumerable, also warum beschwert sich der Compiler? – RaM