2010-05-14 15 views
10

Ho 3 generict nell'elenco Tipo.cast di oggetti alla lista Generico

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

E salvarlo su una variabile con tipo oggetto. Ora ho nedd non Fusioni Torna all'indice a perfom un foreach, un po 'come questo:

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

Ma obj cambiamento contenuti ogni volta, e ho alcuni, come questo:

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

devo un'altra azienda variabile corrente Tipo obj:

Type t = typeof(obj); 

Posso fare qualche cosa del genere ??:

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

Obs: io non sono il tipo di corrente nella lista, ma ho bisogno di lanciare, e io non ora un'altra forma invece:

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

risposta

27

Che problema appiccicoso. Prova questo:

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>; 

Tra c, a, d, c'è 2 nulli e 1 non nullo, o 3 nulli.


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 futuro ho bisogno di più oggetti, non lavoro grazie !! – JoeLoco

+2

lavoro uomo, 7 ore, grazie a lottttttttttttttt !!!!!! – JoeLoco

1

Una soluzione generale come questo (per istanziare un tipo con un parametro generico sulla base di un oggetto System.Type) non è possibile. Se sei veramente solo a che fare con questi tre tipi, anche se, allora siete fortunati perché è abbastanza facile:

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 futuro ho bisogno di più oggetti, dont thank's lavoro !! – JoeLoco

-1

Potrebbe essere necessario fare:

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

non proprio, no. – Femaref

+2

L'elenco richiede un tipo, non funziona grazie !! – JoeLoco

0

No, non puoi lanciare senza andare dietro gli angoli (questo è: riflessione), di tipo generico i parametri devono essere noti al momento della compilazione. Ovviamente si può fare qualcosa di simile:

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

17

sacco di tentativi ed errori me questo dato su SL 5 ma dovrebbe funzionare anche su un normale C#. È inoltre necessario aggiungere LINQ all'elenco di utilizzo per l'ultima metà al lavoro.

List<object> myAnythingList = (value as IEnumerable<object>).Cast<object>().ToList() 

Divertiti!

+0

Questa è l'unica soluzione che ho trovato su Stack Overflow nell'ultima ora che ha funzionato. GRAZIE! Il mio problema era che nella riflessione .Invoke() restituisce e oggetto, che in fase di esecuzione è un elenco . Ma non conosco la classe, solo l'interfaccia IUnifyingDef. Sia la trasmissione diretta che l'uso di Converti() hanno generato eccezioni o non sarebbero riusciti a compilare. – jgerman

+0

il problema con questo approccio è che 'ToList()' crea un altro elenco e non è l'istanza originale – JobaDiniz

+0

Non avrei mai trovato questo da solo. Grazie mille. – nhwilly

2

Ho avuto lo stesso problema e risolto, cercando nello scopo degli oggetti colati. Hai davvero bisogno di trasmetterlo ai tipi generici specifici (chiusi)? Nel mio caso il tipo generico (aperto) aveva un'interfaccia che usavo per lanciarlo.

var list = obj as IUsefulInterface; 

list.MethodThatIAmInterestedIn(); 
0

Ho avuto questo problema durante la scrittura di un attributo di convalida in cui ho ricevuto un oggetto dalla ValidationContext e sapeva che doveva essere una lista, ma non quello che è stato un elenco di. Esso ha generato un'eccezione quando ho provato a lanciare come IEnumerable<object> ma potrebbe essere gettato come IEnumerable che quindi lasciata la .Cast<object>() tramite LINQ.

Alla fine ciò che ha funzionato è stato:

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

Ho incontrato lo stesso problema - ho una collezione che tipo di dati è nota solo in fase di esecuzione e non posso lanciare a nulla. Nessuna delle soluzioni di cui sopra ha funzionato. Alla fine l'ho risolto serializzando su JSON e de-serializzando indietro. Certo che non è l'ideale, ma può aiutare qualcuno.

string jsonString = JsonConvert.SerializeObject(myObject); 
jsonString = "{ values:" + jsonString + "}"; 

JObject j = JObject.Parse(jsonString); 

//now we can iterate over the list 
foreach (var x in j["values"]) 
{ 
    string name = x.ToString(); 
    ... 
} 
Problemi correlati