如何通过参数化类型进行过滤,而不管其参数类型如何?

时间:2012-05-10 18:41:22

标签: c# templates reflection

我想知道某个类型是否为IQueryable。

var t = typeof(IQueryable<int>);
bool isQueryable = (t is IQueryable); // false
bool isAssignableFrom = t.IsAssignableFrom(typeof(IQueryable)); // false
bool nameStartsWithIQueryable = t.Name.StartsWith("IQueryable"); // true

第三种方式 - 查看类型名称的开头 - 有效,但感觉就像是黑客。

还有另一种方法可以实现这个目标吗?

2 个答案:

答案 0 :(得分:5)

使用GetGenericTypeDefinition

bool isQueryable = t.GetGenericTypeDefinition() == typeof(IQueryable<>);

如果你需要处理更深的祖先(你在检查基类型的aganist),你可以写一个辅助方法:

public static bool IsType(Type type, Type ancestor)
{
    while (type != null)
    {
        if (type.IsGenericType)
            type = type.GetGenericTypeDefinition();
        if (type == ancestor)
            return true;
        type = type.BaseType;
    }
    return false;
}

这样称呼它:

bool isQueryable = IsType(typeof(IQueryable<int>), typeof(IQueryable<>));

(请注意,这对实现其他接口的基类型没有帮助,因为对此进行检查需要递归使用Type.GetInterfaces的更多代码。)

答案 1 :(得分:1)

你只有IsAssignableFrom向后,它应该是:

typeof(IQueryable).IsAssignableFrom(t);

我更喜欢在一般情况下使用IsAssignableFrom,因为当你不处理接口时,IsAssignableFrom会告诉你一个类是否是一个隐含的用户定义转换运算符。另外,您不必处理类型层次结构等...