我怎么知道对象是否来自特定的泛型类?

时间:2010-12-30 09:16:46

标签: c# .net generics

假设我有一个对象,那么我怎么知道该对象是否来自特定的泛型类。例如:

public class GenericClass<T> 
{
}    

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

请注意上面的代码会引发异常。无法直接检索泛型类的类型,因为没有提供类型参数的泛型类没有类型。

3 个答案:

答案 0 :(得分:2)

你应该这样做:

    public class GenericClass<T>
    {
    }

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


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

示例:

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

答案 1 :(得分: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);
}

用法:

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

这些测试通过:

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 :(得分:1)

关键是Type.GetGenericTypeDefinition。这是一个完整的例子:

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
    }
}