简体   繁体   English

c#在运行时动态创建通用列表

[英]c# Create generic list dynamically at runtime

Following the example on this post , I found out how to create a list of generic types dynamically. 下面就例如这个帖子 ,我发现了如何动态地创建通用类型的列表。 Now, my issue is that I want to ADD items to the created list from an unknown source list - is there some way to achieve this? 现在,我的问题是我想将项目从未知来源列表添加到创建的列表中,有什么方法可以实现?

EDIT I start with a source list containing business objects, but I absolutely need the right type of my output list, because of downstream bindings that require it. 编辑我从包含业务对象的源列表开始,但是由于需要下游绑定,因此我绝对需要正确的输出列表类型。

My non-compiling code is as follows: 我的非编译代码如下:

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
}

There's a few reasons this code doesn't work. 有一些原因导致此代码无法正常工作。

Firstly, you need to create an instance of a concrete type. 首先,您需要创建一个具体类型的实例。 You're taking a non-generic interface ( IList ) and trying to create a generic type from it. 您正在使用一个非泛型接口( IList ),并试图从中创建一个泛型类型。 You need typeof(List<>) . 您需要typeof(List<>)

Secondly, you're calling AddItem which isn't a method on IList . 其次,您要调用AddItem ,它不是IList上的方法。 You need to call Add , which is why the code doesn't compile. 您需要调用Add ,这就是为什么代码无法编译的原因。

This code will do what you want: 此代码将执行您想要的操作:

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);
}

However, the assumption that sourceList[0] holds the correct type may come to bite you. 但是, sourceList[0]拥有正确类型的假设可能会让您大吃一惊。 If that list contains a sequence of objects that are not type compatible with the first item in the list then any attempt to add to res will fail. 如果该列表包含与列表中第一项类型不兼容的一系列对象,则添加到res任何尝试都会失败。 As was mentioned in the comment, you'd be better off creating a List<object> to hold the items. 正如评论中提到的,最好创建一个List<object>来保存项目。

I would recommend moving your code into a generic class or function, moving the reflection to a higher level: 我建议将您的代码移到通用类或函数中,将反射移到更高的层次:

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();
}

To call it: 调用它:

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});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM