GenericType上的IsAssignableFrom

时间:2012-03-02 20:00:08

标签: c# reflection

不确定我是否可以这样做,但我正在尝试查看某个类型是否继承了具有通用约束的其他类型。

这是我要找的课程:

public class WorkoutCommentStreamMap : ClassMapping<WorkoutCommentStream>...

这是测试

var inheritableType = typeof(NHibernate.Mapping.ByCode.Conformist.ClassMapping<>);
var isMappedObject = inheritableType.IsAssignableFrom(typeof(WorkoutCommentStreamMap));

如果我将第一行更改为以下,则可行。但这违背了我的例子的目的。我的后备工作是在我想要查找的所有对象上放置一个自定义的非泛型接口并使用相同的调用。

var inheritableType = typeof(NHibernate.Mapping.ByCode.Conformist.ClassMapping<WorkoutCommentStream>);

5 个答案:

答案 0 :(得分:7)

泛型类型定义和封闭泛型类型之间没有继承关系。因此,IsAssignableFrom无效。

但是,我使用这个小扩展方法来实现你的后续:

public static bool IsGenericTypeOf(this Type t, Type genericDefinition)
{
    Type[] parameters = null;
    return IsGenericTypeOf(t, genericDefinition, out parameters);
}

public static bool IsGenericTypeOf(this Type t, Type genericDefinition, out Type[] genericParameters)
{
    genericParameters = new Type[] { };
    if (!genericDefinition.IsGenericType)
    {
        return false;
    }

    var isMatch = t.IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition();
    if (!isMatch && t.BaseType != null)
    {
        isMatch = IsGenericTypeOf(t.BaseType, genericDefinition, out genericParameters);
    }
    if (!isMatch && genericDefinition.IsInterface && t.GetInterfaces().Any())
    {
        foreach (var i in t.GetInterfaces())
        {
            if (i.IsGenericTypeOf(genericDefinition, out genericParameters))
            {
                isMatch = true;
                break;
            }
        }
    }

    if (isMatch && !genericParameters.Any())
    {
        genericParameters = t.GetGenericArguments();
    }
    return isMatch;
}

使用样本:

Nullable<int> value = 9;
Assert.IsTrue(value.GetType().IsGenericTypeOf(typeof(Nullable<>)));

答案 1 :(得分:5)

您可以使用BaseTypeIsGenericTypeGetGenericTypeDefinition来提升层次结构并尝试找到它:

public bool IsClassMapping(Type t)
{
    while (t != null)
    {
        if (t.IsGenericType &&
            t.GetGenericTypeDefinition() == typeof(ClassMapping<>))
        {
            return true;
        }
        t = t.BaseType;
    }
    return false;
}

答案 2 :(得分:3)

你要做的事情是行不通的,并且在MSDN documentation中明确地提到了它:

  

泛型类型定义不能从闭合构造中分配   类型。也就是说,您无法分配封闭的构造类型   MyGenericList<int>MyGenericList<T>

类型的变量

IsAssignableFrom似乎有点矫枉过正;你能用BaseType来检查匹配的类型吗?

答案 3 :(得分:1)

MyType<>MyType<T>MyType<ConcreteType>之间永远不存在继承关系!因此,它们永远不会兼容分配。

一个例外是具有inout关键字的通用参数的接口类型。

答案 4 :(得分:0)

也许这会有所帮助?

    public static bool IsConcreteGenericOf(this Type type, Type openGeneric)
    {
        if (!type.IsGenericType)
            return false;
        if (!openGeneric.IsGenericType)
            return false;
        if (!openGeneric.IsGenericTypeDefinition)
            return false;

        return type.GetGenericTypeDefinition() == openGeneric;
    }

Sorta类似于Jon Skeet的回答,他打败了我。