2010-05-14 28 views
10

Ich habe 3 Liste Typ Liste.Cast Objekt auf generische Liste

List<Contact> = new List<Contact>(); 
List<Address> = new List<Address>(); 
List<Document> = new List<Document>(); 

Und speichern Sie es auf eine Variable mit Typ Objekt. Jetzt nedd i do Cast Zurück zur Liste ein foreach perfom, einige wie folgt aus:

List<Contact> = (List<Contact>)obj; 

Aber obj Inhalt ändern jedes Mal, und ich habe einige wie folgt aus:

List<???> = (List<???>)obj; 

Ich habe eine andere variable Halte Strom obj Typ:

Type t = typeof(obj); 

kann ich tun, etwas, was wie die ??:

List<t> = (List<t>)obj; 

Obs: I der aktuelle Typ in der Liste nicht, aber ich werfen müssen, und ich nicht jetzt eine andere Form statt:

List<Contact> = new List<Contact>(); 

Antwort

27

Was für ein klebriges Problem. Versuchen Sie dies:

List<Contact> c = null; 
List<Address> a = null; 
List<Document> d = null; 

object o = GetObject(); 

c = o as List<Contact>; 
a = o as List<Address>; 
d = o as List<Document>; 

Zwischen c, a und d, gibt es 2 Nullen und 1 nicht Null, oder 3 Nullen.


Take 2:

object o = GetObject(); 
IEnumerable e = o as IEnumerable; 
IEnumerable<Contact> c = e.OfType<Contact>(); 
IEnumerable<Address> a = e.OfType<Address>(); 
IEnumerable<Document> d = e.OfType<Document>(); 
+0

in Zukunft ich mehr Objekte benötigen, arbeiten nicht thank's !! – JoeLoco

+2

es Mann arbeiten, 7 Stunden, Dank lottttttttttttttt !!!!!! – JoeLoco

1

Eine allgemeine Lösung wie diese (eine Art mit einem generischen Parameter instanziiert basierend auf ein System.Type Objekt) ist nicht möglich. Wenn Sie sich wirklich nur mit diesen drei Typen zu tun, aber dann haben Sie Glück, denn es ist ziemlich einfach:

Type t = typeof(obj); 

if (t == typeof(List<Contact>)) { 
    var contactList = (List<Contact>)obj; 
    // do stuff with contactList 

} else if (t == typeof(List<Address>)) { 
    var addressList = (List<Address>)obj; 
    // do stuff with addressList 

} else if (t == typeof(List<Document>)) { 
    var documentList = (List<Document>)obj; 
    // do stuff with documentList 
} 
+0

in der Zukunft brauche ich mehr Objekte, arbeite nicht danke !! – JoeLoco

-1

Sie könnten tun müssen:

if(object is List) 
{ 
    list = (List)object 
} 
+1

nicht wirklich, nein. – Femaref

+2

Liste erfordern eine Art, arbeiten nicht danken ist !! – JoeLoco

0

Nein, kann man nicht werfen, ohne um Ecken zu gehen (das ist: Reflexion), generischer Typ Parameter müssen zur Kompilierzeit bekannt sein. Sie können so etwas wie dies natürlich tun:

content.Where(o => o is type).ToList().Foreach(stuff);

17

Viele Versuch und Irrtum gab mir diese auf SL 5, aber es sollte auch auf einer regulären C# arbeiten. Sie müssen außerdem LINQ zu Ihrer Verwendungsliste hinzufügen, damit die letzte Hälfte funktioniert.

Genießen Sie!

+0

Dies ist die einzige Lösung, die ich über Stack-Überlauf in der letzten Stunde gefunden habe, die gearbeitet haben. VIELEN DANK! Mein Problem war, dass in der Reflexion .Invoke() zurückkehrt und Objekt, die zur Laufzeit ist eine List . Aber ich kenne die Klasse nicht, nur die Schnittstelle IUnifyingDef. Sowohl das direkte Casting als auch die Verwendung von Convert() warfen Ausnahmen oder konnten nicht kompiliert werden. – jgerman

+0

das Problem mit diesem Ansatz ist, dass 'ToList()' eine andere Liste erstellen und es ist nicht die ursprüngliche Instanz – JobaDiniz

+0

würde ich nie auf meiner eigenen gefunden haben. Ich danke dir sehr. – nhwilly

2

Ich hatte das gleiche Problem und löste es mit Blick auf den Zweck der gegossenen Objekte. Müssen Sie es wirklich auf die spezifischen (geschlossenen) generischen Typen umwandeln? In meinem Fall hatte der (offene) generische Typ eine Schnittstelle, mit der ich ihn umgewandelt habe.

var list = obj as IUsefulInterface; 

list.MethodThatIAmInterestedIn(); 
0

Ich hatte dieses Problem, wenn eine Validierung Attribut zu schreiben, wo ich von der ValidationContext ein Objekt empfangen und wusste, dass es brauchte eine Liste zu sein, aber nicht, was es war eine Liste. Es wurde eine Ausnahme ausgelöst, als ich versuchte, es als IEnumerable<object> zu werfen, aber es könnte als IEnumerable umgewandelt werden, die dann die .Cast<object>() über linq erlaubte.

Am Ende, was funktioniert hat war:

var enumerable = listObject as IEnumerable; 
var list = enumerable.Cast<object>().ToList(); 
0

ich in gleiches Problem lief - ich habe eine Sammlung, den Datentyp nur zur Laufzeit bekannt ist, und ich kann es nicht auf etwas werfen. Keine der obigen Lösungen hat funktioniert. Schließlich löste ich es durch Serialisierung zu JSON und Deserialisierung zurück. Natürlich ist es nicht ideal, kann aber jemandem helfen.