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

Dzy*_*ann 4 c# reflection

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

public void MyMethod(IList myList)
{
}
Run Code Online (Sandbox Code Playgroud)

我有一个类,您可以将 IList 关联到它,您也可以添加一个 NewItem 函数,但我希望能够使用默认的空构造函数添加项目,以防用户未设置 NewItem 函数。

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

Jon*_*lis 7

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

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

例如,使用

IList list = new List<string>();
Run Code Online (Sandbox Code Playgroud)

会给Is generic collection of System.String,并且

IList list = new ArrayList();
Run Code Online (Sandbox Code Playgroud)

会给 Is not generic

  • 呵呵。SO 将受益于更好地突出显示 C#6 字符串插值语法。 (4认同)

Yac*_*sad 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();
}
Run Code Online (Sandbox Code Playgroud)