我正在通过Reflection.Emit
制作玩具.NET语言,不可避免的功能之一是检查泛型的实例是否满足其约束,这很容易添加,除非有一个约束指向另一个类型参数,例如(在C#中)
class MyClass<T, U> where U : T {}
或
class Foo<T> {
class Bar<U : T> {}
}
我一直在通过Type.IsAssignableFrom(Type)
检查约束,但是GenericTypeParameterBuilder
覆盖了它以抛出NotSupportedException
。如何在不引发此错误的情况下检查类型约束是否满足?
编辑:
我有个想法,我可以通过调用Type.MakeGenericType(Type[])
来解决问题,并捕获我提供的类型不匹配时抛出的错误,但是显然TypeBuilders
不在乎,并且有可能发出不符合约束的类型(例如MyClass<void, int>
)。
编辑2:
这是对评论中请求的答复。
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
class Demo {
public static void Main() {
AssemblyBuilder assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("demo"), AssemblyBuilderAccess.ReflectionOnly);
ModuleBuilder module = assembly.DefineDynamicModule("demo");
TypeBuilder type = module.DefineType("MyType");
GenericTypeParameterBuilder[] @params = type.DefineGenericParameters("T", "U");
@params[1].SetBaseTypeConstraint(@params[0]);
Type[] args = new[] {typeof(IEnumerable<char>), typeof(string)};
bool meetsConstraints = true;
for (int i = 0; i < 2; i++) {
meetsConstraints &= @params[i].IsAssignableFrom(args[i]); // error is here
}
Console.WriteLine(meetsConstraints);
}
}