标题有点模糊。我想知道这是否可能:
string typeName = <read type name from somwhere>;
Type myType = Type.GetType(typeName);
MyGenericClass<myType> myGenericClass = new MyGenericClass<myType>();
显然,MyGenericClass被描述为:
public class MyGenericClass<T>
现在,编译器报错“找不到类型或名称空间‘myType’”。一定有办法解决的。
一些额外的如何运行剪刀代码。假设您有一个类似的类
public class Encoder() {
public void Markdown(IEnumerable<FooContent> contents) { do magic }
public void Markdown(IEnumerable<BarContent> contents) { do magic2 }
}
假设在运行时你有一个FooContent
如果您能够在编译时绑定,那么您将需要
var fooContents = new List<FooContent>(fooContent)
new Encoder().Markdown(fooContents)
但是,在运行时不能这样做。要在运行时做到这一点,你可以按照下面的代码来做:
var listType = typeof(List<>).MakeGenericType(myType);
var dynamicList = Activator.CreateInstance(listType);
((IList)dynamicList).Add(fooContent);
动态调用Markdown(IEnumerable<FooContent> contents)
new Encoder().Markdown( (dynamic) dynamicList)
注意在方法调用中使用dynamic。在运行时dynamicList将是List<FooContent>(另外也为IEnumerable<FooContent>),因为即使使用dynamic仍然植根于强类型语言,运行时绑定器将选择适当的Markdown方法。如果没有精确的类型匹配,它将寻找对象参数方法,如果两者都不匹配,将引发运行时绑定异常,警告没有方法匹配。
这种方法的明显缺点是在编译时损失了巨大的类型安全性。尽管如此,沿着这些行的代码将允许您在非常动态的意义上操作,在运行时仍然是您所期望的完全类型。