使用Reflection.Emit实现通用接口

Ant*_*ony 5 c# generics reflection.emit

我正在使用Reflection.Emit来定义一个新类型,我想要实现的类型IComparable(T),其中T将是新定义的类型.

class DefinedType : IComparable<DefinedType>
{
//...
}
Run Code Online (Sandbox Code Playgroud)

在我看来,我有一个鸡和蛋的问题.

作为后备,我总是可以实现IComparable,但如果可能的话,我会喜欢通用接口; 我只是看不出如何使用Emit来实现它,因为在我定义之前类型不存在.

Lua*_*aan 4

这应该有效:

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();
Run Code Online (Sandbox Code Playgroud)

幸运的是,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();
Run Code Online (Sandbox Code Playgroud)

您不必以任何方式将生成的方法绑定到接口,它们的签名相同就足够了。进行显式接口实现可能会有点棘手,但您不应该需要这样做。