2009-12-14 13 views
7

En alguna parte de mi código estoy pasando una colección de objetos del tipo T. No sé qué colección concreta se me va a pasar, aparte de que impone IEnumerable.Cómo obtener el tipo contenido en una colección a través de la reflexión

En tiempo de ejecución, necesito averiguar qué tipo de T es (por ejemplo, System.Double, System.String, etc.).

¿Hay alguna manera de averiguarlo?

ACTUALIZACIÓN: Debería aclarar un poco más el contexto en el que estoy trabajando (un proveedor de Linq).

Mi función tiene una firma como la siguiente, donde consigo el tipo de la colección como un parámetro:

string GetSymbolForType(Type collectionType) 
{ 

} 

¿Hay alguna manera de obtener el tipo collectionType los objetos contenidos?

+1

del tipo de colección solo puede obtener el tipo de objetos contenidos en colecciones genéricas. Si trabajas con colecciones clásicas, no tendrás una buena oportunidad aquí que no sea iterar sobre los objetos y preguntar específicamente por sus tipos. –

Respuesta

14

De Matt Warren's Blog:

internal static class TypeSystem { 
    internal static Type GetElementType(Type seqType) { 
     Type ienum = FindIEnumerable(seqType); 
     if (ienum == null) return seqType; 
     return ienum.GetGenericArguments()[0]; 
    } 
    private static Type FindIEnumerable(Type seqType) { 
     if (seqType == null || seqType == typeof(string)) 
      return null; 
     if (seqType.IsArray) 
      return typeof(IEnumerable<>).MakeGenericType(seqType.GetElementType()); 
     if (seqType.IsGenericType) { 
      foreach (Type arg in seqType.GetGenericArguments()) { 
       Type ienum = typeof(IEnumerable<>).MakeGenericType(arg); 
       if (ienum.IsAssignableFrom(seqType)) { 
        return ienum; 
       } 
      } 
     } 
     Type[] ifaces = seqType.GetInterfaces(); 
     if (ifaces != null && ifaces.Length > 0) { 
      foreach (Type iface in ifaces) { 
       Type ienum = FindIEnumerable(iface); 
       if (ienum != null) return ienum; 
      } 
     } 
     if (seqType.BaseType != null && seqType.BaseType != typeof(object)) { 
      return FindIEnumerable(seqType.BaseType); 
     } 
     return null; 
    } 
} 
+1

Esto hizo el truco. Gracias. –

0
Type t = null 
foreach(object o in list) 
{ 
o.GetType(); 
} 

obtendrá el tipo de objeto.

A continuación, probablemente debería probar para sus tipos deseados:

if(t == typeof(myClass)) 
{ 
dosomething(); 
} 
else if (t == typeof(myOtherClass)) 
{ 
dosomethingelse(); 
} 
0

Cant que acaba de utilizar t.GetType() para hacer esto.

0

¿Por qué no implementar simplemente un IEnumerable<T> en su lugar? EG:

public void MyFunc<T>(IEnumerable<T> objects)

Aparte de eso, que sería mejor comprobar el tipo de cada objeto individual usando is o .GetType lugar de tratar de trabajar hacia fuera desde el propio envase.

Sin embargo, si eso no es una opción y realmente necesita saber el tipo de contenedor base, básicamente debe verificar usando is para ver qué interfaces implementa (por ejemplo: IList<int>, etc.). Las probabilidades son que el tipo de su matriz va a ser genérico, lo que significa que tratar de trabajar desde su nombre hasta su tipo de datos será bastante desordenado.

8
myCollection.GetType().GetGenericArguments() 

devolverá una matriz del tipo args.

+4

solo funciona en tipos genéricos. –

0

Bueno, yo soy manera de la manera tarde aquí, pero no debe este trabajo:

public static bool ThatCollectionIsOfType<T>(IEnumerable<T> collection, Type got) 
    { 
     if (**typeof(T)** == got) //this line should be good to go... 
     { 
      return true; 
     } 

    } 
0

utilizo mucho dinámico y esto es un problema de vez en cuando.

Matt Davis en el clavo pero se necesita el índice :)

public static void PopulateChildCollection<T>(T currentObject, string singlePropertyName) 
{ 
    dynamic currentObjectCollection = ReflectionTools.GetPropertyValue(currentObject, singlePropertyName); 
    Type collectionType = currentObjectCollection.GetType().GetGenericArguments()[0]; 

El tipo será lo que se puede esperar, es el tipo de objeto contenido en la recolección y no cualquiera de los tipos genéricos de los alrededores eso.

Cuestiones relacionadas