Quiero escribir un método que use Reflection para indicar si un Type dado implementa IList<T>
. Por ejemplo:¿Cómo puedo saber si un Type implementa IList <>?
IsGenericList(typeof(int)) // should return false
IsGenericList(typeof(ArrayList)) // should return false
IsGenericList(typeof(IList<int>)) // should return true
IsGenericList(typeof(List<int>)) // should return true
IsGenericList(typeof(ObservableCollection<int>)) // should return true
En mi uso, que se puede suponer que el tipo siempre será una instancia de tipo genérico (o algo que no es genérica en absoluto).
Desafortunadamente, esto no es tan fácil como debería ser. La solución obvia:
public bool IsGenericList(Type type)
{
return typeof(IList<>).IsAssignableFrom(type);
}
no funciona; siempre devuelve falso. Aparentemente, los tipos genéricos no instanciados como IList<>
no implementan IsAssignableFrom la forma en que yo esperaba: IList<>
no se puede asignar desde List<T>
.
También he intentado esto:
public bool IsGenericList(Type type)
{
if (!type.IsGenericType)
return false;
var genericTypeDefinition = type.GetGenericTypeDefinition();
return typeof(List<>).IsAssignableFrom(genericTypeDefinition);
}
es decir, girar type
en su no una instancia genérica, como IList<int>
->IList<>
, y luego tratar IsAssignableFrom nuevo. Que devolverá verdadero si el tipo es una instancia IList<T>
como IList<int>
, IList<object>
, etc, pero que devuelve false para clases que implementan IList<T>
como List<int>
, ObservableCollection<double>
, etc., por lo que aparentemente IList<>
no es asignable a partir List<>
. Nuevamente, no es lo que esperaría.
¿Cómo hago para escribir IsGenericList y hacer que funcione como en los ejemplos anteriores?
+1 - Esto funciona, y es la única solución que hay actualmente: me di cuenta de que tenía esto después de publicar lo mismo. –
Nunca vi @ para usar palabras clave como nombres de variables en ningún código de producción. – VVS
Buena solución. :) Sin embargo, un pequeño punto: el uso de los símbolos @ generalmente no es una práctica recomendada. (Simplemente podría llamar a la variable 'i' o' curInterface' en su lugar para resolver el choque de nombres.) – Noldorin