sto*_*ran 2 c# generics reflection
在我项目的某个地方,我需要创建一个具体的泛型类型,将泛型类型定义(带有单个参数)和该参数的类型作为参数。
为此,我编写了一个非常简单的方法:
Type MakeGenericType(Type definition, Type parameter)
{
return definition.MakeGenericType(parameter);
}
Run Code Online (Sandbox Code Playgroud)
但是,在某些时候,我需要List<List<T>>使用给定的元素 type创建一个类型T。尽管我能够List<List<T>>使用我的方法创建一个类型,但随后尝试从中创建一个具体类型List<List<int>>失败了 - 请参阅下面的代码:
var genericList = MakeGenericType(typeof(List<>), typeof(List<>)); // success
MakeGenericType(genericList, typeof(int)); // exception
Run Code Online (Sandbox Code Playgroud)
mscorlib.dll 中发生类型为“System.InvalidOperationException”的未处理异常
附加信息:System.Collections.Generic.List`1[System.Collections.Generic.List`1[T]] 不是 GenericTypeDefinition。MakeGenericType 只能在 Type.IsGenericTypeDefinition 为 true 的类型上调用。
此外,以下调用甚至不会编译:
MakeGenericType(typeof(List<List<>>), typeof(int));
Run Code Online (Sandbox Code Playgroud)
我已经检查了这个关于IsGenericTypeDefinition和之间差异的问题ContainsGenericParameters。但是,我仍然没有想法,如何处理像genericList.
显然,使用反射我可以构造一个类型对象,这与它无关 - 这对我来说很困惑。
所以问题是,如何从包含泛型类型定义作为参数的泛型创建具体类型?有可能吗?
您需要将传递的类型分解为泛型类型定义,并使用以下内容自下而上构建生成的泛型类型:
static Type MakeGenericType(Type definition, Type parameter)
{
var definitionStack = new Stack<Type>();
var type = definition;
while (!type.IsGenericTypeDefinition)
{
definitionStack.Push(type.GetGenericTypeDefinition());
type = type.GetGenericArguments()[0];
}
type = type.MakeGenericType(parameter);
while (definitionStack.Count > 0)
type = definitionStack.Pop().MakeGenericType(type);
return type;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1837 次 |
| 最近记录: |