2009-12-06 19 views
8

mejor manera de ilustrar mi pregunta es con este código de ejemplo:¿Cómo comparar el tipo de objeto con un tipo genérico, irrelevante para el argumento genérico?

class Item {} 
    class Container<T> {} 
    class Program 
    { 
    static void DoSomething(object something) 
    { 
     if(typeof(Item) == something.GetType()) 
     { 
     System.Console.WriteLine("Item"); 
     } 
     else if(typeof(Container<>) == something.GetType()) 
     { 
     System.Console.WriteLine("Container<>"); 
     } 
    } 

    static void Main(string[] args) 
    { 
     DoSomething(new Item()); 
     DoSomething(new Container<int>()); 
    } 
    } 

La línea siguiente no funcionará:

else if(typeof(Container<>) == something.GetType()) 

¿Es una manera de hacer que funcione sin cambiar de forma explícita Container<> en Container<int>? Quiero saber que el objeto es del tipo 'Container' y realmente no me interesan Container<int> o Container<string>. ¿Alguna sugerencia que no sean docenas de líneas de reflexión?

Respuesta

23

Probar:

typeof(Container<>) == something.GetType().GetGenericTypeDefinition() 

Tenga en cuenta que esto sólo se devolverá verdadero si el tipo real es Container<T>. No funciona para tipos derivados. Por ejemplo, se regresará false para lo siguiente:

class StringContainer : Container<string> 

Si tiene que hacer que funcione para este caso, se debe recorrer la jerarquía de herencia y probar cada clase base por ser Container<T>:

static bool IsGenericTypeOf(Type genericType, Type someType) 
{ 
    if (someType.IsGenericType 
      && genericType == someType.GetGenericTypeDefinition()) return true; 

    return someType.BaseType != null 
      && IsGenericTypeOf(genericType, someType.BaseType); 
} 
Cuestiones relacionadas