I'm using Reflection.Emit to define a new type, and I'd like the type to implement IComparable(T)
, where T
would be the newly defined type.
class DefinedType : IComparable<DefinedType>
{
//...
}
It seems to me like I have a chicken-and-egg problem.
As a fallback, I can always just implement IComparable
, but if possible I'd like the generic interface; I just can't see how I can do it using Emit, because the type doesn't exist before I define it.
This should work:
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();
Fortunately, TypeBuilder inherits from Type, so you can use it in MakeGenericType
.
As a verification, this works:
var o1 = Activator.CreateInstance(type);
var o2 = Activator.CreateInstance(type);
typeof(IComparable<>).MakeGenericType(o1.GetType()).GetMethod("CompareTo").Invoke(o1, new [] { o2 }).Dump();
You don't have to bind the generated method to the interface in any way, it's enough that their signature is the same. Doing explicit interface implementation might be a bit more tricky, but you shouldn't need that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With