如何检查给定值是否为通用列表?

74 c# generics reflection list

public bool IsList(object value)
    {
        Type type = value.GetType();
        // Check if type is a generic list of any type
    }
Run Code Online (Sandbox Code Playgroud)

检查给定对象是列表还是可以转换为列表的最佳方法是什么?

Vic*_*ues 105

对于那些喜欢使用扩展方法的人:

public static bool IsGenericList(this object o)
{
    var oType = o.GetType();
    return (oType.IsGenericType && (oType.GetGenericTypeDefinition() == typeof(List<>)));
}
Run Code Online (Sandbox Code Playgroud)

所以,我们可以这样做:

if(o.IsGenericList())
{
 //...
}
Run Code Online (Sandbox Code Playgroud)

  • 对于.Net Core,需要稍微修改一下`return oType.GetTypeInfo().IsGenericType && oType.GetGenericTypeDefinition()== typeof(List <>);` (2认同)

Jam*_*res 76

if(value is IList && value.GetType().IsGenericType) {

}
Run Code Online (Sandbox Code Playgroud)

  • 您需要使用System.Collections添加; 在源文件的顶部.我建议的IList接口不是通用版本(因此第二次检查) (11认同)
  • 这不起作用 - 我得到以下异常 - 值为IList使用泛型类型'System.Collections.Generic.IList <T>'需要'1'类型参数 (4认同)
  • 这不起作用.我猜在4.0 IList <T>!= IList?无论如何,我必须检查它是否是通用的IEnumerable,然后检查我想检查的属性是否存在,"Count".我认为这个弱点部分是为什么WCF将所有List <T>转换为T []的原因. (3认同)

Eoi*_*ell 14

 bool isList = o.GetType().IsGenericType 
                && o.GetType().GetGenericTypeDefinition() == typeof(IList<>));
Run Code Online (Sandbox Code Playgroud)


小智 8

下面是一个在 .NET Standard 中工作的实现,并且针对接口工作:

    public static bool ImplementsGenericInterface(this Type type, Type interfaceType)
    {
        return type
            .GetTypeInfo()
            .ImplementedInterfaces
            .Any(x => x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == interfaceType);
    }
Run Code Online (Sandbox Code Playgroud)

这是测试(xunit):

    [Fact]
    public void ImplementsGenericInterface_List_IsValidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IList<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IEnumerable<>)));
        Assert.True(list.GetType().ImplementsGenericInterface(typeof(IReadOnlyList<>)));
    }

    [Fact]
    public void ImplementsGenericInterface_List_IsNotInvalidInterfaceTypes()
    {
        var list = new List<string>();
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(string)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IDictionary<,>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(IComparable<>)));
        Assert.False(list.GetType().ImplementsGenericInterface(typeof(DateTime)));
    }
Run Code Online (Sandbox Code Playgroud)


Ati*_*ziz 6

public bool IsList(object value) {
    return value is IList 
        || IsGenericList(value);
}

public bool IsGenericList(object value) {
    var type = value.GetType();
    return type.IsGenericType
        && typeof(List<>) == type.GetGenericTypeDefinition();
}
Run Code Online (Sandbox Code Playgroud)


小智 6

根据 Victor Rodrigues 的回答,我们可以设计另一种泛型方法。事实上,原来的解决方案可以简化为只有两行:

public static bool IsGenericList(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>);
}

public static bool IsGenericList<T>(this object Value)
{
    var t = Value.GetType();
    return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<T>);
}
Run Code Online (Sandbox Code Playgroud)


Yas*_*asi 6

我正在使用以下代码:

public bool IsList(Type type) => type.IsGenericType && (
            (type.GetGenericTypeDefinition() == typeof(List<>))
            || (type.GetGenericTypeDefinition() == typeof(IList<>))
            );
Run Code Online (Sandbox Code Playgroud)


BFr*_*ree 5

if(value is IList && value.GetType().GetGenericArguments().Length > 0)
{

}
Run Code Online (Sandbox Code Playgroud)