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

C# 如何获取IList项的基础类型?,c#,reflection,C#,Reflection,我有一个方法可以接收IList。是否有办法获取IList的项目类型 public void MyMethod(IList myList) { } 我有一个可以关联IList的类,您也可以添加NewItem函数,但我希望能够使用默认的空构造函数添加项,以防用户没有设置NewItem函数 如何获取基础项的类型?如果它是一个IList,我会知道怎么做,但我不能更改API,因为我可以接收任何类型的实现IList的集合,唯一的限制是,代码没有强制执行,即我们接收的集合中的所有项都是同一类型的。因为它是I

我有一个方法可以接收
IList
。是否有办法获取IList的项目类型

public void MyMethod(IList myList)
{
}
我有一个可以关联IList的类,您也可以添加NewItem函数,但我希望能够使用默认的空构造函数添加项,以防用户没有设置NewItem函数


如何获取基础项的类型?如果它是一个
IList
,我会知道怎么做,但我不能更改API,因为我可以接收任何类型的实现IList的集合,唯一的限制是,代码没有强制执行,即我们接收的集合中的所有项都是同一类型的。

因为它是
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>();

如果传递的类型是非泛型的,则会给出非泛型的
,,而您可能会有一个类型抓取包(例如):

使用System.Collections.Generic;
使用System.Collections.Specialized;
使用System.Linq;
名称空间控制台EAPP1
{
公共课程
{
公共静态void Main(字符串[]args)
{
var list=new ArrayList();
添加(“你好”);
列表。添加(0);
var types=GetTypes(列表);
foreach(类型中的var itemType)
{
Console.WriteLine(itemType.ToString());
}
Console.ReadLine();
}
公共静态HashSet GetTypes(IList列表)
{
var types=newhashset();
foreach(列表中的变量项)
{
var newType=item.GetType();
如果(!types.Contains(newType))
{
类型。添加(新类型);
}
}
返回类型;
}
}
}

您必须使GetTypes函数更加复杂,才能处理泛型情况。

这里是一个启发式算法,您可以从这里开始。大多数(如果不是全部)通用列表接口都继承自
IEnumerable
,因此您可以检查列表是否实现了
IEnumerable
。如果没有,则检查第一个元素的类型,当然假设列表将包含相同类型的元素。如果列表为空,则此方法返回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();
}
public静态类型HeuristicallyDetermineType(IList myList)
{
变量可枚举_类型=
myList.GetType()
.GetInterfaces()
.Where(i=>i.IsGenericType&&i.GenericTypeArguments.Length==1)
.FirstOrDefault(i=>i.GetGenericTypeDefinition()==typeof(IEnumerable));
if(可枚举_类型!=null)
返回可枚举的_类型.GenericTypeArguments[0];
如果(myList.Count==0)
返回null;
返回myList[0]。GetType();
}

您可以这样做:创建一个列表,然后在附加列表中添加类型

   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());
   }
IList iListObj=新列表
{
1234,
“哈罗德·纳尔逊”,
假,,
“A”
};
var typeList=新列表();
foreach(iListObj中的var项目)
{
typeList.Add(item.GetType());
}

获取列表或IList的基本类型没有不同的方法。因为它们将覆盖这些方法。你可以这样做
list.GetType().GenericTypeArguments[0]
请注意,当您想要获取列表中项目的类型时,这是相同的方式。您是否可以假设
myList
也将实现
IList
?API以
IList
的形式发送给您的基础集合类型是什么?@M.kazemAkhgary-真的吗?我只是假设它做不到。那么你怎么知道列表中的项目是同一类型的呢?也许它包含一个整数和一个字符串。因此,如果能更好地突出显示C#6字符串插值语法,将受益匪浅。对于.NET4.5以下的应用程序,请改用。
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();
}
   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());
   }