【问题标题】:How to find the member type of a list如何查找列表的成员类型
【发布时间】:2015-12-25 14:57:35
【问题描述】:

到目前为止,我有这个:

if (o.GetType().IsGenericType && o is System.Collections.IEnumerable)
        {
            var typefield = typeof(List<object>).GetFields().Where(f => f.Name == "T").ToArray();
            Type T = (Type)(typefield[0].GetValue(o));
            addButton.Enabled = true;
            if (((System.Collections.IList)o).Count > 0)
            {
                removeButton.Enabled = true;
            }
            comboBox1.Enabled = true;
            comboBox1.Items.Clear();

            foreach (var item in Assembly.GetAssembly(T).GetTypes().Where(x => T.IsAssignableFrom(x) && !x.IsAbstract))
            {
                comboBox1.Items.Add(item);
            }
            comboBox1.DisplayMember = "Name";   
        }

但它在“Type T = (Type)(typefield[0].GetValue(o));”行上崩溃因为数组是空的,也就是说上一行没有工作。

问题: 假设通过第一行的所有内容都是一个List,我应该如何确定列表中的对象类型。 (注意检查成员的类型是不够的。成员很可能是从列表定义中指定的 Type 派生的。)

附言 我在这里读到,我的第一行是将某些内容确定为列表的最佳方法: If object is Generic List 你有更准确的方法吗?

【问题讨论】:

  • 可能应该是 typeof(System.Collections.IEnumerable)?
  • (o.GetType().IsGenericType &amp;&amp; o is IList)怎么样
  • 你真正想要完成什么?
  • 您在寻找o.GetType().GetGenericArguments()吗?

标签: c# list types


【解决方案1】:

我认为一个答案可能是这种方法:

public IEnumerable<Type> GetGenericIEnumerables(object o) {
    return o.GetType()
            .GetInterfaces()
            .Where(t => t.IsGenericType == true
                && t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            .Select(t => t.GetGenericArguments()[0])
            .ToList();
}

你可以这样使用它:

var type= GetGenericIEnumerables(o).FirstOrDefault();

如果o不是IEnumerable&lt;T&gt;,则类型为null,否则返回T

当 o 本身不是泛型并且继承自 IEnumerable&lt;T&gt; 时,它也能完美运行,例如对于 string,函数将返回 char

基于jason's asnwer

【讨论】:

    【解决方案2】:

    如果我理解正确,您可以通过

    获得通用参数
    Type.GetGenericArguments()
    

    https://msdn.microsoft.com/en-us/library/system.type.getgenericarguments%28v=vs.110%29.aspx

    【讨论】:

      【解决方案3】:

      要确定List&lt;T&gt; 的类型,您可以使用Type.GetGenericArguments()

      var o = new List<int>();
      
      if (o.GetType().IsGenericType && o is IList)
      {
          var args = o.GetType().GetGenericArguments()
      
          if(args.Count() == 1)
          {
              Type T = args[0];
      
              // rest of code
          }
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用GetGenericArguments。此代码将为您提供列表中元素的类型o

        if (o.GetType().IsGenericType && o is System.Collections.IEnumerable)
        {
            var itemType = o.GetType().GetGenericArguments()[0];
            //Console.WriteLine(itemType);
        }
        

        如果你有

        var o = new List<string>{ "a", "b" };
        

        它会给你

        System.String;
        

        【讨论】:

          猜你喜欢
          • 2023-03-05
          • 2020-07-18
          • 2011-11-13
          • 1970-01-01
          • 1970-01-01
          • 2020-05-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多