2010-05-14 15 views
10

Tengo 3 lista de tipos genéricos.Objeto emitido a la lista genérica

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

Y guárdalo en una variable con tipo de objeto. Ahora i nedd rechaces Volver a la lista debe jugar un foreach, algunos como este:

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

Pero obj cambio de contenido cada vez, y tengo algo como esto:

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

Tengo otra de mantenimiento variable Tipo actual obj:

Type t = typeof(obj); 

¿Puedo hacer algo como eso ??:

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

Obs: Yo no el tipo actual de la lista pero necesito fundido, y yo no ahora otra forma en su lugar:

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

Respuesta

27

Qué problema pegajosa. Prueba esto:

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

entre C, A, y D, hay 2 valores nulos y 1 no nulo, o 3 valores nulos.


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

en el futuro necesito más objetos, no trabajo gracias !! – JoeLoco

+2

trabajo hombre, 7 horas, gracias muchotttttttttttttt !!!!!! – JoeLoco

1

Una solución general como esta (para crear instancias de un tipo con un parámetro genérico basado en un objeto System.Type) no es posible. Si usted está realmente sólo se ocupan de estos tres tipos, sin embargo, entonces estás de suerte porque es bastante fácil:

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

en el futuro necesito más objetos, no trabajo gracias !! – JoeLoco

-1

Es posible que tenga que hacer:

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

no realmente, no. – Femaref

+2

¡La lista requiere un tipo, no funciona gracias! – JoeLoco

0

No, no se puede lanzar sin tener que pasar por las esquinas (esto es: la reflexión), de tipo genérico los parámetros deben conocerse en tiempo de compilación. Por supuesto, puede hacer algo como esto:

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

17

Un montón de ensayo y error me dio esto en 5 SL sino que también debe trabajar en un habitual de C#. También necesita agregar LINQ a su lista de uso para que funcione la última mitad.

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

Enjoy!

+0

Esta es la ÚNICA solución que he encontrado en Stack Overflow en la última hora que funcionó. ¡GRACIAS! Mi problema fue que en la reflexión .Invoke() devuelve y el objeto, que en el tiempo de ejecución es una lista . Pero no conozco la clase, solo la interfaz IUnifyingDef. Tanto la conversión directa como el uso de Convert() arrojaron excepciones o no compilarían. – jgerman

+0

el problema con ese enfoque es que 'ToList()' crea otra lista y no es la instancia original – JobaDiniz

+0

Nunca hubiera encontrado esto por mi cuenta. Muchas gracias. – nhwilly

2

Tuve el mismo problema y lo resolví observando el propósito de los objetos fundidos. ¿De verdad necesitas lanzarlo a los tipos genéricos específicos (cerrados)? En mi caso, el tipo genérico (abierto) tenía una interfaz que usé para convertirlo.

var list = obj as IUsefulInterface; 

list.MethodThatIAmInterestedIn(); 
0

he tenido este problema al escribir un Atributo de validación donde recibí un objeto de la ValidationContext y sabía que tenía que ser una lista, pero no es lo que era una lista de. Lanzó una excepción cuando traté de convertirlo como IEnumerable<object> pero podría ser lanzado como IEnumerable que luego permitió el .Cast<object>() a través de linq.

Al final lo que funcionó fue:

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

me encontré con el mismo problema - Tengo una colección que tipo de datos sólo se conoce en tiempo de ejecución y no puedo echarlo a nada. Ninguna de las soluciones anteriores funcionó. Finalmente lo resolví serializando a JSON y deserializando de nuevo. Por supuesto que no es ideal, pero puede ayudar a alguien.

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(); 
    ... 
} 
Cuestiones relacionadas