如何获取IList项的基础类型?

时间:2015-12-10 21:12:06

标签: c# reflection

我有一个接收IList的方法。有没有办法获得IList的项目类型?

public void MyMethod(IList myList)
{
}

我有一个可以将IList关联到的类,你也可以添加一个NewItem函数,但我希望能够在用户没有设置NewItem函数的情况下使用默认的空构造函数添加项目。

如何获取基础项的类型?如果它是IList<T>我会知道怎么做,但是我无法更改API,因为我可以接收任何实现IList的集合,只有代码强制执行的限制,是我们收到的藏品中的所有商品都属于同一类型。

4 个答案:

答案 0 :(得分:4)

由于它是IList,您首先必须检查它是否真的是通用的:

if (list.GetType().IsGenericType)
      Console.WriteLine($"Is generic collection of {list.GetType().GenericTypeArguments[0]}");
else
      Console.WriteLine("Is not generic");

例如,使用

IList list = new List<string>();

会给Is generic collection of System.String

IList list = new ArrayList();

会给Is not generic

答案 1 :(得分:1)

这是一个可以开始的启发式算法。大多数(如果不是全部)通用列表接口都继承自IEnumerable<T>,因此您可以检查列表是否实现IEnumerable<T>。如果它没有,你检查第一个元素的类型,当然假设列表包含相同类型的元素。如果列表为空,则此方法返回null。

public static Type HeuristicallyDetermineType(IList myList)
{
    var enumerable_type = 
        myList.GetType()
        .GetInterfaces()
        .Where(i => i.IsGenericType && i.GenericTypeArguments.Length == 1)
        .FirstOrDefault(i => i.GetGenericTypeDefinition() == typeof (IEnumerable<>));

    if (enumerable_type != null)
        return enumerable_type.GenericTypeArguments[0];

    if (myList.Count == 0)
        return null;

    return myList[0].GetType();
}

答案 2 :(得分:1)

你可以做这样的事情有一个List,并在另一个List中添加类型。

   IList<object> iListObj = new List<object>
   {
        1234,
       "Harold Nelson",
       false,
       'A'
   };
   var typeList = new List<object>();
   foreach (var item in iListObj)
   {
       typeList.Add(item.GetType());
   }

enter image description here

答案 3 :(得分:0)

如果传递的类型是非通用的,那么你可能有一个类型的抓包(例如):

using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

namespace ConsoleApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var list = new ArrayList();
            list.Add("Hello");
            list.Add(0);

            var types = GetTypes(list);

            foreach (var itemType in types)
            {
                Console.WriteLine(itemType.ToString());
            }

            Console.ReadLine();
        }

        public static HashSet<Type> GetTypes(IList list)
        {
            var types = new HashSet<Type>();

            foreach (var item in list)
            {
                var newType = item.GetType();
                if (!types.Contains(newType))
                {
                    types.Add(newType);
                }
            }

            return types;
        }
    }
}

您必须使GetTypes函数更复杂,以处理一般情况。