c# 在运行时动态创建泛型列表
c# Create generic list dynamically at runtime
按照 this post 上的示例,我了解了如何动态创建泛型类型列表。
现在,我的问题是我想从未知来源列表 ADD 项目到创建的列表 - 有什么方法可以实现这个吗?
编辑
我从包含业务对象的源列表开始,但我绝对需要正确类型的输出列表,因为下游绑定需要它。
我的非编译代码如下:
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
}
此代码不起作用的原因有几个。
首先,您需要创建一个具体类型的实例。您正在使用一个非泛型接口 (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>
来保存这些项目。
我建议将您的代码移动到通用 class 或函数中,将反射移动到更高级别:
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});
按照 this post 上的示例,我了解了如何动态创建泛型类型列表。 现在,我的问题是我想从未知来源列表 ADD 项目到创建的列表 - 有什么方法可以实现这个吗?
编辑 我从包含业务对象的源列表开始,但我绝对需要正确类型的输出列表,因为下游绑定需要它。
我的非编译代码如下:
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
}
此代码不起作用的原因有几个。
首先,您需要创建一个具体类型的实例。您正在使用一个非泛型接口 (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>
来保存这些项目。
我建议将您的代码移动到通用 class 或函数中,将反射移动到更高级别:
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});