2013-04-24 5 views
16

Warum kann ich keinen List<AnonymousObject> in einen List<dynamic> umwandeln? Ich habe diesen Code ein:Liste des anonymen Typs in Liste der dynamischen Objekte umwandeln

var datasource = someList.Select(o => new { x = o.A, y = o.B }); 
dgvSomeGridView.DataSource = datasource.ToList(); 
dgvSomeGridView.DataBind(); 

Dann greife ich auf die GridView.DataSource mit dem folgenden Code:

var ds = ((List<dynamic>)dgvSomeGridView.DataSource); 
.... 

Aber es wirft einen Fehler auf der Linie, wo ich es List<dynamic> werfen, heißt es:

Das Objekt System.Collections.Generic.List'1[<>f__AnonymousType0'8[System.Int32,System.String]] konnte nicht in den Typ System.Collections.Generic.List'1[System.Object] umgewandelt werden.

Warum kann ich nicht eine Liste von anonymen Typ in einen dynamic gegossen, oder als der Fehler sagt zu einem object Typ? Wie kann ich das beheben?

Mein Code ist in C#, Framework 4.0, Build in VS2010 Pro, Plattform ist ASP.NET.

Bitte helfen, danke im Voraus.

Antwort

35

Da List<T> ist in-Variante nicht kovarianten, so dass Sie sich in IEnumerable<dynamic> gegossen, die Co-Variante unterstützt:

var ds = ((IEnumerable<dynamic>)dgvSomeGridView.DataSource).ToList(); 

Weitere information about covariant

+1

vergessen Sie nicht "hinzufügen mit System.Linq; ' in Ihrem Dokumentenkopf, falls Sie noch nicht haben –

6

Zum einen mit generischem Casting funktioniert so nicht. Diese Besetzung ist ungültig:

List<string> source = GetStrings(); 
List<object> source2 = (List<object>) source; 

Der Grund ist, dass List nicht co-Variante ist. Wenn es so wäre, könntest du source2.Add(source2); und plötzlich Source1 selbst enthalten wenn es nur Strings hätte.

Zweitens, Anonymous types sind nur Compiler deklariert Klassen mit Readonly-Eigenschaften und Wert Gleichheit Semantik. Wenn Sie eine Klasse mit schreibgeschützten Eigenschaften und Gleichheitssemantik erstellt haben, entspricht Ihre Klasse einem anonymen Typ, außer dass Ihr Typ einen vom Entwickler bestimmten Namen hat, während der anonyme Typ einen vom Compiler bestimmten Namen hat. Anon-Typen sind nicht besonders.

Drittens dynamic Variablen sind eine Möglichkeit, Compiler-Typ zu überprüfen. Sie umgehen nicht die Laufzeitprüfung. Sie können die Syntax C# casting verwenden, um den Typ explizit in dynamic zu konvertieren ... Hinweis: Dies ist kein Cast! Sie können keine Laufzeitumwandlung für einen Typ ausführen, der zur Laufzeit nicht existiert.

Operationen, die Ausdrücke vom Typ dynamic enthalten, werden jedoch vom Compiler nicht aufgelöst oder typisiert. Der Compiler stellt Informationen zur Operation zusammen, und diese Informationen werden später zur Auswertung der Operation zur Laufzeit verwendet. Als Teil des Prozesses werden Variablen vom Typ dynamisch in Variablen vom Typ Objekt kompiliert. Daher gibt type dynamic nur zur Kompilierzeit und nicht zur Laufzeit ein.

static void convertToDynamic() 
{ 
    dynamic d; 
    int i = 20; 
    d = (dynamic)i; 
    Console.WriteLine(d); 

    string s = "Example string."; 
    d = (dynamic)s; 
    Console.WriteLine(d); 

    DateTime dt = DateTime.Today; 
    d = (dynamic)dt; 
    Console.WriteLine(d); 

} 
// Results: 
// 20 
// Example string. 
// 2/17/2009 9:12:00 AM 

Schließlich, wenn Sie noch eine List<dynamic> wollen, dies tun:

var anonList = GetAnonList(); 
List<dynamic> dynamicList = anonList.Select(x => (dynamic)x).ToList(); 

Aber man könnte genauso gut und leicht:

var anonList = GetAnonList(); 
List<object> objectList = anonList.Cast<object>().ToList(); 
+0

Großartig, das funktioniert für mich! –