How can I find out if an object is derived from a specific generic class?

Suppose I have an object from where I can find out if an object is derived from a specific general class. For example:

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

note that the code above throws an exception. The type of a generic class cannot be obtained directly, because there is no type for a generic class without the type parameter provided.

+6
generics c #
source share
3 answers

You should do something like this:

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

Example:

  static void Main(string[] args) { var generic = new GenericClassInherited<int>(); var isTrue = IsDeriveFrom(generic); } 
+2
source share
 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); } 

Using:

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

These tests 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<>))); } 
+2
source share

Key Type.GetGenericTypeDefinition . Here is a complete example:

 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
source share

All Articles