2012-06-02 24 views
25

Estoy tratando de determinar si un tipo de tiempo de ejecución es algún tipo de tipo de colección. Lo que tengo a continuación funciona, pero parece extraño que tenga que nombrar los tipos que creo que son tipos de colección en una matriz como la que hice.¿Cómo determinar si un tipo es un tipo de colección?

En el siguiente código, el motivo de la lógica genérica se debe a que, en mi aplicación, espero que todas las colecciones sean genéricas.

bool IsCollectionType(Type type) 
{ 
    if (!type.GetGenericArguments().Any()) 
     return false; 

    Type genericTypeDefinition = type.GetGenericTypeDefinition(); 
    var collectionTypes = new[] { typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>), typeof(List<>) }; 
    return collectionTypes.Any(x => x.IsAssignableFrom(genericTypeDefinition)); 
} 

¿Cómo podría refactorizar este código para ser más inteligente o más simple?

+0

Una cosa a tener en cuenta es que por lo general no quiere considerar 'string' como una colección de' char's, a pesar de que implementa IEnumerable '' . – svick

Respuesta

48

Realmente todos estos tipos heredan IEnumerable. Sólo puede verificar por él:

bool IsEnumerableType(Type type) 
{ 
    return (type.GetInterface(nameof(IEnumerable)) != null); 
} 

o si realmente se necesita para comprobar si ICollection:

bool IsCollectionType(Type type) 
{ 
    return (type.GetInterface(nameof(ICollection)) != null); 
} 

vistazo a "Sintaxis" parte:

+0

Haha. Realmente fue así de simple. Por alguna razón, pensé que eso no funcionaría y no lo intenté. –

+1

La jerarquía de herencia en el documento no indica las interfaces implementadas. Pero mirando la sección de sintaxis lo hará. – svick

+0

@svick: ¿Qué hay de Lista public class : IList , ICollection , \t IEnumerable, IList, ICollection, IEnumerable ? – Ruben

2

Se puede utilizar esta método de ayuda para comprobar si un tipo implementa una interfaz genérica abierta. En su caso se puede usar DoesTypeSupportInterface(type, typeof(Collection<>))

public static bool DoesTypeSupportInterface(Type type,Type inter) 
{ 
    if(inter.IsAssignableFrom(type)) 
     return true; 
    if(type.GetInterfaces().Any(i=>i. IsGenericType && i.GetGenericTypeDefinition()==inter)) 
     return true; 
    return false; 
} 

o simplemente puede comprobar la genérica IEnumerable no. Todas las interfaces de colección heredan de él. Pero no llamaría a ningún tipo que implemente IEnumerable una colección.

+0

O use la solución [que se encuentra aquí] (http://stackoverflow.com/a/1075059/122781) que funciona para tipos genéricos además de las interfaces genéricas. – HappyNomad

1

Todos ellos heredarán IEnumerable(), lo que significa comprobar its there debería ser suficiente:

+3

Lo mismo ocurre con la cadena que conduce a un falso positivo – War

0

Puede utilizar LINQ, buscar un nombre de interfaz como

yourobject.GetType().GetInterfaces().Where(s => s.Name == "IEnumerable") 

Si esto tiene valores es una instancia de IEnumerable.

+3

Lo mismo ocurre con la cadena que conduce a un falso positivo – War

2

Sé que este hilo es antiguo, pero he aquí un ejemplo moderno a partir del 20 de julio de 2015 según la palabra clave Microsoft is.

if(collection is ICollection) return true; 
+0

La pregunta es cómo determinar si un * tipo * es una colección, no una instancia de objeto. –

Cuestiones relacionadas