检查泛型类型

3
我想检查一个通用变量是否属于某种类型,但不想检查它的通用部分。
假设我有一个变量是`List`,另一个是`List`。我只想检查它是否属于类型`List<>`。
if(variable is List) {}

而不是

if (variable is List<int> || variable is List<double>) {}

这个是否可能?

谢谢

3个回答

9
variable.GetType().IsGenericType && 
            variable.GetType().GetGenericTypeDefinition() == typeof(List<>)

当然,这仅适用于变量是List<T>类型且不是派生类的情况。如果您想检查它是否为List<T>或其派生类,则应遍历继承层次结构并针对每个基类检查上述语句:

static bool IsList(object obj)
{
    Type t = obj.GetType();
    do {
        if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>))
            return true;
        t = t.BaseType;
    } while (t != null);
    return false;
}

GetGenericTypeDefinition()比没有参数的MakeGenericType()更自然一些。 - weiqure
是的。完整的代码是第二个。第一行只关注于想法。 - Mehrdad Afshari

6

您可以通过反射来测试确切的类型:

    object list = new List<int>();

    Type type = list.GetType();
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
    {
        Console.WriteLine("is a List-of-" + type.GetGenericArguments()[0].Name);
    }

个人而言,我会选择使用 IList<T> - 它比具体的 List<T> 更加通用:

    foreach (Type interfaceType in type.GetInterfaces())
    {
        if (interfaceType.IsGenericType
            && interfaceType.GetGenericTypeDefinition()
            == typeof(IList<>))
        {
            Console.WriteLine("Is an IList-of-" +
                interfaceType.GetGenericArguments()[0].Name);
        }
    }

马克,type.GetGenericTypeDefinition() == typeof(List<>) 不就足够检查了吗? - Royi Namir
@Royi 如果你是指第一个代码块,那么不是:如果它不是一个泛型类型,则 GetGenericTypeDefinition() 会抛出异常;如果你指的是第二个代码块:有更多种类的“列表”而不仅仅是 List<T> - Marc Gravell

5
Type t = variable.GetType();
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>))
{
    // do something
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接