c# 在运行时动态创建泛型列表

本文关键字:泛型 列表 创建 动态 运行时 | 更新日期: 2023-09-27 17:56:27

按照这篇文章中的示例,我发现了如何动态创建泛型类型的列表。现在,我的问题是我想将项目从未知源列表添加到创建的列表中 - 有没有办法实现这一目标?

编辑我从包含业务对象的源列表开始,但我绝对需要正确类型的输出列表,因为下游绑定需要它。

我的非编译代码如下:

IList<object> sourceList; // some list containing custom objects
Type t = typeof(IList).MakeGenericType(sourceList[0].GetType());
IList res = (IList)Activator.CreateInstance(t);
foreach (var item in sourceList) {
    reportDS.Add(item); // obviously does not compile
}

c# 在运行时动态创建泛型列表

这段代码不起作用有几个原因。

首先,您需要创建具体类型的实例。您正在获取一个非泛型接口(IList ),并尝试从中创建泛型类型。你需要typeof(List<>).

其次,您调用的AddItem不是IList的方法。你需要调用Add,这就是代码无法编译的原因。

此代码将执行您想要的操作:

IList<object> sourceList; // some list containing custom objects
Type t = typeof(List<>).MakeGenericType(sourceList[0].GetType());
IList res = (IList)Activator.CreateInstance(t);
foreach(var item in sourceList)
{
    res.Add(item);
}

但是,假设sourceList[0]持有正确的类型可能会咬你。如果该列表包含与列表中的第一项类型不兼容的对象序列,则任何添加到res的尝试都将失败。正如评论中提到的,您最好创建一个List<object>来保存这些项目。

我建议将代码移动到泛型类或函数中,将反射移动到更高级别:

private static List<T> CloneListAs<T>(IList<object> source)
{
    // Here we can do anything we want with T
    // T == source[0].GetType()
    return source.Cast<T>().ToList();
}

要调用它:

IList<object> sourceList; // some list containing custom objects
// sourceList = ...
MethodInfo method = typeof(this).GetMethod("CloneListAs");
MethodInfo genericMethod = method.MakeGenericMethod(sourceList[0].GetType());
var reportDS = genericMethod.Invoke(null, new[] {sourceList});