我正在尝试使用 Reflection.Emit 发出一个将在运行时从多个接口(interface)继承的类,但我无法提前知道哪些接口(interface)。
根据 MSDN/TypeBuilder.DefineMethodOverride :
To override a method of a base class or to implement a method of an interface, simply emit a method with the same name and signature as the method to be overridden or implemented
这是我重写接口(interface)方法的代码:
private void OverrideMethod(TypeBuilder typeBuilder,
Type interfaceToOverride,
MethodInfo methodToOverride)
{
// Create the method stub
MethodBuilder methodBuilder = typeBuilder.DefineMethod(
methodToOverride.Name,
MethodAttributes.Public
| MethodAttributes.HideBySig
| MethodAttributes.NewSlot
| MethodAttributes.Virtual
| MethodAttributes.Final,
CallingConventions.HasThis,
methodToOverride.ReturnType,
methodToOverride.GetParameters().Select(p => p.ParameterType).ToArray()
);
// Implement the overriding method
ILGenerator il = methodBuilder.GetILGenerator();
// ... a bunch of calls to il.Emit ...
// Return
il.Emit(OpCodes.Ret);
}
这是有效的,除非我从两个接口(interface)继承,这两个接口(interface)都有一个同名的方法。显然,这是因为我没有为该方法提供完全限定的名称。我不确定如何正确执行此操作。
将 methodToOverride.Name
更改为 interfaceToOverride.FullName + "."+ methodToOverride.Name
不起作用:发出时出现错误,“TypeLoadException:类没有实现。
使用 DefineMethodOverride
部分有效,但出于某种原因,当我针对嵌套接口(interface)测试它时却没有。此外,上面链接的文档明确表示不要这样做。
解决此问题的正确方法是什么?
最佳答案
正确的方法是定义一个名为 <InterfaceName>.<MethodName>
的方法然后调用 TypeBuilder.DefineMethodOverride
.
The DefineMethodOverride method is used when a method body and a method declaration have different names.
在您的例子中,方法体名称是 <InterfaceName>.<MethodName>
, 而方法声明名称是 <MethodName>
.所以用 TypeBuilder.DefineMethodOverride
就可以了.
示例用法:
private void OverrideMethod(TypeBuilder typeBuilder,
Type interfaceToOverride,
MethodInfo methodToOverride)
{
// Create the method stub
MethodBuilder methodBuilder = typeBuilder.DefineMethod(
/* Change method name here */
string.Format("{0}.{1}", interfaceToOverride.FullName,
methodToOverride.Name),
MethodAttributes.Public
| MethodAttributes.HideBySig
| MethodAttributes.NewSlot
| MethodAttributes.Virtual
| MethodAttributes.Final,
CallingConventions.HasThis,
methodToOverride.ReturnType,
methodToOverride.GetParameters().Select(p => p.ParameterType).ToArray()
);
// Implement the overriding method
ILGenerator il = methodBuilder.GetILGenerator();
// ... a bunch of calls to il.Emit ...
// Return
il.Emit(OpCodes.Ret);
// And define a methodimpl, which consists of a pair of metadata tokens.
// One token points to an implementation, and the other token points
// to a declaration that the body implements
typeBuilder.DefineMethodOverride(methodBuilder, methodToOverride);
}
注意
实际上,您可以使用任何 名称定义您的方法(使用TypeBuilder.DefineMethod
)。但它应该不同于 <MethodName>
并且您必须调用 TypeBuilder.DefineMethodOverride
将方法体与方法声明“链接”起来。
关于c# - 发出一个类覆盖两个具有相同名称的接口(interface)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14693103/