我使用Reflection.Emit来定义新类型,我希望实现IComparable(T)
的类型,其中T
将是新定义的类型。
class DefinedType : IComparable<DefinedType>
{
//...
}
在我看来,我有鸡和蛋的问题。
作为后备,我总是可以实现IComparable
,但如果可能的话,我喜欢通用接口;我只是不知道如何使用Emit来做到这一点,因为在我定义它之前类型并不存在。
答案 0 :(得分:3)
这应该有效:
var tb = mb.DefineType("Test", TypeAttributes.Public);
var iface = typeof(IComparable<>).MakeGenericType(tb);
tb.AddInterfaceImplementation(iface);
var meb = tb.DefineMethod("CompareTo", MethodAttributes.Public | MethodAttributes.Virtual, typeof(int), new [] { tb } );
var il = meb.GetILGenerator();
il.ThrowException(typeof(Exception));
var type = tb.CreateType();
幸运的是,TypeBuilder继承自Type,因此您可以在MakeGenericType
中使用它。
作为验证,这有效:
var o1 = Activator.CreateInstance(type);
var o2 = Activator.CreateInstance(type);
typeof(IComparable<>).MakeGenericType(o1.GetType()).GetMethod("CompareTo").Invoke(o1, new [] { o2 }).Dump();
您不必以任何方式将生成的方法绑定到接口,它们的签名就足够了。做显式接口实现可能会有点棘手,但你不应该那样。
答案 1 :(得分:2)
在致电MakeGenericType()
以将IComparable<>
变为IComparable<DefinedType>
时,您可以将其传递给TypeBuilder
。代码看起来像:
var boundComparerType = typeof(IComparable<>).MakeGenericType(typeBuilder);
typeBuilder.AddInterfaceImplementation(boundComparerType);