2010-12-30 13 views
6

Supongamos que tengo un objeto, entonces, ¿cómo podría saber si el objeto se deriva de una clase genérica específica? Por ejemplo:¿Cómo podría saber si un objeto se deriva de una clase genérica específica?

public class GenericClass<T> 
{ 
}  

public bool IsDeriveFrom(object o) 
{ 
    return o.GetType().IsSubclassOf(typeof(GenericClass)); //will throw exception here 
} 

tenga en cuenta que el código anterior arrojará una excepción. El tipo de la clase genérica no se puede recuperar directamente porque no hay ningún tipo para una clase genérica sin un parámetro de tipo proporcionado.

Respuesta

2

su debe hacer algo como esto:

public class GenericClass<T> 
    { 
    } 

    public class GenericClassInherited<T> : GenericClass<T> 
    { 
    } 


    public static bool IsDeriveFrom(object o) 
    { 
     return o.GetType().BaseType.GetGenericTypeDefinition() == typeof(GenericClass<>); 
    } 

Ejemplo:

static void Main(string[] args) 
    { 
     var generic = new GenericClassInherited<int>(); 
     var isTrue = IsDeriveFrom(generic); 
    } 
+1

que puede tirar tantas excepciones cuando no hay un tipo base, o no hay una definición de tipo genérico, y se produce un error cuando 'Bar: Foo: GenericFoo ' y en y en. – jason

+0

Lo sé, pero de todos modos funciona para el ejemplo anterior. Y @Edison puede agregar excepciones manejándose solo. Es solo una idea. –

+0

He intentado con el código de ejemplo y he agregado algunas excepciones para manejar el código. Es un trabajo perfecto ahora. Otras respuestas aquí también me dieron información útil, pero no sé por qué no puedo votar esas respuestas útiles. –

2
bool IsDerivedFrom(Type type, Type genericBaseTypeDefinition) { 
    Contract.Requires(type != null); 
    Contract.Requires(genericBaseTypeDefinition != null); 
    Contract.Requires(genericBaseTypeDefinition.IsGenericBaseTypeDefinition); 
    Type baseType = type.BaseType; 
    if (baseType == null) { 
     return false; 
    } 

    if (baseType.IsGenericType) { 
     Type generic = baseType.GetGenericTypeDefinition(); 
     if (generic == null) { 
      return false; 
     } 
     return generic == genericBaseTypeDefinition; 
    } 

    return IsDerivedFrom(baseType, genericBaseTypeDefinition); 
} 

Uso:

bool derived = IsDerivedFrom(typeof(Foo), typeof(GenericFoo<>)); 

Estas pruebas Pass:

class GenericFoo<T> { } 
class DerivedGenericFoo<T> : GenericFoo<T> { } 
class Foo : GenericFoo<int> { } 
class Bar : Foo { } 
class Animal { } 

[Fact] 
public void DerivedGenericFoo_derives_from_open_GenericFoo() { 
    Assert.Equal(
     true, 
     IsDerivedFrom(
      typeof(DerivedGenericFoo<int>), 
      typeof(GenericFoo<>) 
     ) 
    ); 
} 

[Fact] 
public void Foo_derives_from_open_GenericFoo() { 
    Assert.Equal(true, IsDerivedFrom(typeof(Foo), typeof(GenericFoo<>))); 
} 

[Fact] 
public void Bar_derives_from_open_GenericFoo() { 
    Assert.Equal(true, IsDerivedFrom(typeof(Bar), typeof(GenericFoo<>))); 
} 

[Fact] 
public void Animal_does_not_derive_from_open_GenericFoo() { 
    Assert.Equal(false, IsDerivedFrom(typeof(Animal), typeof(GenericFoo<>))); 
} 
1

La clave es Type.GetGenericTypeDefinition. He aquí un ejemplo completo:

class Generic<T> { } 

class Derived<T> : Generic<T> { } 
class NonDerived<T> { } 

class Program 
{ 
    static bool IsDerivedFromGenericT(Type type) 
    { 
     if (!type.IsGenericType) 
      return false; 
     if (type.GetGenericTypeDefinition() == typeof(Generic<>)) 
      return true; 
     if (type.BaseType == null) 
      return false; 
     return IsDerivedFromGenericT(type.BaseType); 
    } 

    static void Main(string[] args) 
    { 
     var b1 = IsDerivedFromGenericT(new Derived<int>().GetType()); // true 
     var b2 = IsDerivedFromGenericT(new Derived<string>().GetType()); // true 
     var b3 = IsDerivedFromGenericT(new NonDerived<string>().GetType()); // false 
    } 
} 
+1

definitivamente, este parece un mejor ejemplo –

Cuestiones relacionadas