我有一点问题.
我想这样做:
Type[] classes = new Type[]{ Class1, Class2 };
foreach(Type t in classes){
List<t> list = new List<t>();
}
Run Code Online (Sandbox Code Playgroud)
有办法做到这一点吗?
您不能在运行时转换为泛型类型,因为泛型中的类型需要在编译时解析.
您可以使用反射以动态方式创建泛型类型,但除非您对强制转换进行硬编码,否则您获得的所有内容都是对象.
我不能真正说出你想要的是什么,我不得不同意这是一个XY问题.我倾向于做出这样一种冒昧的陈述:这是一个设计问题,它试图解决,而不是直接解决设计问题,或者询问你想要直接实现的问题.
您可以使用以下代码创建类型,然后该dynamic类型可用于在不知道/关心它是列表或什么是以下内容的情况下对各种成员进行类型化:List<T>T
using System;
using System.Collections.Generic;
namespace ConsoleApplication61
{
class Program
{
static void Main(string[] args)
{
dynamic o = CreateGeneric(typeof(List<>), typeof(int));
o.Add(1);
Console.WriteLine(o[0]);
Console.Read();
}
public static object CreateGeneric(Type generic, Type innerType, params object[] args)
{
System.Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
return Activator.CreateInstance(specificType, args);
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的示例duck类型Add方法和Indexer.DLR在运行时进行类型处理和鸭子类型化 - 例如,知道它1是一个int.
只是为了澄清,我可能不会在生产中使用这样的代码(除非你的要求非常具体需要这个),并且任何类型不匹配的问题都会在运行时发生; 因此您需要非常准确地键入(有限的IntelliSense)或具有良好的错误处理.
感谢此博客文章的CreateGeneric方法.
这假定.NET 4具有新的CLR.正如@MartinLiversage也指出的那样,这个特定的示例假设您以强类型的方式使用列表.在我的例子中,我传递int给List<int>隐藏在一个dynamic.
自从它发布以来,我们一直在使用.NET 4.我们有一个大型应用程序,具有更大的代码库.dynamic在应用程序中不使用一次,在测试代码库中只使用几次.这并不是说"不要使用它",而是说"大多数时候,你不需要它".
你可以这样做:
foreach(Type t in classes)
{
var listType = typeof(List<>).MakeGenericType(t);
var instance = Activator.CreateInstance(listType);
}
Run Code Online (Sandbox Code Playgroud)