【问题标题】:How do I check if a given value is a generic list?如何检查给定值是否是通用列表?
【发布时间】:2010-10-22 02:33:38
【问题描述】:
public bool IsList(object value)
    {
        Type type = value.GetType();
        // Check if type is a generic list of any type
    }

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

【问题讨论】:

标签: c# reflection list generics


【解决方案1】:

对于喜欢使用扩展方法的你们:

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

所以,我们可以这样做:

if(o.IsGenericList())
{
 //...
}

【讨论】:

  • 对于.Net Core,需要稍微修改为return oType.GetTypeInfo().IsGenericType &amp;&amp; oType.GetGenericTypeDefinition() == typeof(List&lt;&gt;);
  • 像魅力一样工作!如果你只有类型而不是对象,这对你有用!谢谢!!
  • 检查IList&lt;&gt; 会更安全吗?
【解决方案2】:
using System.Collections;

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

}

【讨论】:

  • 这不起作用 - 我得到以下异常 - 值为 IList 使用泛型类型 'System.Collections.Generic.IList' 需要 '1' 类型参数
  • 需要使用 System.Collections 添加;在您的源文件之上。我建议的 IList 接口不是通用版本(因此第二次检查)
  • 你是对的。这就像一个魅力。我在我的 Watch 窗口中对此进行了测试,却忘记了丢失的命名空间。我更喜欢这个解决方案,非常简单
  • 这不起作用。我猜想在 4.0 IList != IList?无论如何,我必须检查它是否是通用的和 IEnumerable,然后检查我想要检查的属性“计数”是否存在。我想这个弱点是 WCF 将所有 List 变成 T[] 的部分原因。
  • @Edza 不正确。这通常List&lt;T&gt;ObservableCollection&lt;T&gt; 实现 IList 后有效。
【解决方案3】:
 bool isList = o.GetType().IsGenericType 
                && o.GetType().GetGenericTypeDefinition() == typeof(IList<>));

【讨论】:

    【解决方案4】:
    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();
    }
    

    【讨论】:

      【解决方案5】:
      if(value is IList && value.GetType().GetGenericArguments().Length > 0)
      {
      
      }
      

      【讨论】:

      • 我认为您需要调用 GetType() 例如value.GetType().GetGenericArguments().Length > 0
      【解决方案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>);
      }
      

      【讨论】:

        【解决方案7】:

        这是一个适用于 .NET Standard 的实现,并且适用于接口:

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

        这里是测试(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)));
            }
        

        【讨论】:

          【解决方案8】:

          我正在使用以下代码:

          public bool IsList(Type type) => type.IsGenericType && (
                      (type.GetGenericTypeDefinition() == typeof(List<>))
                      || (type.GetGenericTypeDefinition() == typeof(IList<>))
                      );
          

          【讨论】:

            【解决方案9】:

            可能最好的方法是这样做:

            IList list = value as IList;
            
            if (list != null)
            {
                // use list in here
            }
            

            这将为您提供最大的灵活性,并允许您使用许多实现IList 接口的不同类型。

            【讨论】:

            • 这不会按照要求检查它是否是 generic 列表。
            猜你喜欢
            • 2015-08-25
            • 2016-02-24
            • 1970-01-01
            • 2023-02-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-11
            • 2022-09-23
            • 1970-01-01
            相关资源
            最近更新 更多