我正在使用Reflection.Emit定义一个新类型,我希望这个类型可以实现IComparable(T)
接口,其中T
将是新定义的类型。
class DefinedType : IComparable<DefinedType>
{
//...
}
对我来说,这似乎是一个先有鸡还是先有蛋的问题。
如果没有办法,我可以实现IComparable
接口,但如果可能的话,我更想使用通用接口;只是我无法通过Emit实现,因为在定义类型之前该类型不存在。
我正在使用Reflection.Emit定义一个新类型,我希望这个类型可以实现IComparable(T)
接口,其中T
将是新定义的类型。
class DefinedType : IComparable<DefinedType>
{
//...
}
对我来说,这似乎是一个先有鸡还是先有蛋的问题。
如果没有办法,我可以实现IComparable
接口,但如果可能的话,我更想使用通用接口;只是我无法通过Emit实现,因为在定义类型之前该类型不存在。
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();
您不需要以任何方式将生成的方法绑定到接口,只要它们的签名相同即可。显式接口实现可能会有点棘手,但您不应该需要那样做。
当调用 MakeGenericType()
把 IComparable<>
转换为 IComparable<DefinedType>
时,您只需将其传递给您的 TypeBuilder
即可。代码可能如下所示:
var boundComparerType = typeof(IComparable<>).MakeGenericType(typeBuilder);
typeBuilder.AddInterfaceImplementation(boundComparerType);
addInterfaceImplementation
,你可以在构建好一个新类型后,在你的TypeBuilder
上调用它。难道你不可以使用那个方法事后将Comparable<YourType>
添加到你的类型中吗? - Jeroen VannevelCreateType
一次。 - AnthonyDefinedTypeBase
和class DefinedType : DefinedTypeBase, IComparable<DefinedTypeBase>
。 - Anthony