我正在使用Mono.Cecil生成一个程序集,该程序集包含一个派生类,该类覆盖导入的基类中的特定方法.覆盖方法是一个"隐式"覆盖.问题是我无法弄清楚如何将其指定为覆盖.
我正在使用以下代码来创建覆盖方法.
void CreateMethodOverride(TypeDefinition targetType,
TypeDefinition baseClass, string methodName, MethodInfo methodInfo)
{
// locate the matching base class method, which may
// reside in a different module
MethodDefinition baseMethod = baseClass
.Methods.First(method => method.Name.Equals(methodName));
MethodDefinition newMethod = targetType.Copy(methodInfo);
newMethod.Name = baseMethod.Name;
newMethod.Attributes = baseMethod.Attributes;
newMethod.ImplAttributes = baseMethod.ImplAttributes;
newMethod.SemanticsAttributes = baseMethod.SemanticsAttributes;
targetType.Methods.Add(newMethod);
}
Run Code Online (Sandbox Code Playgroud)
我的理解是隐式覆盖必须与继承方法具有相同的签名.使用上面的代码,当我在Reflector中查看结果方法时,基类和派生类方法具有完全相同的签名,即"public virtual void f(int param)".
我已经尝试删除显式的"虚拟"属性,但随后派生的方法最终为"public void f(int param)".
如何让派生方法具有正确的"public override void f(int param)"签名?
注意:我有一个扩展方法("TypeDefinition.Copy"),它克隆MethodInfo并通过导入所有引用的类型等返回MethodDefinition.
Jb *_*ain 11
在您的基类中,假设您生成以下方法:
public virtual void f(int);
Run Code Online (Sandbox Code Playgroud)
您必须确保将标志IsVirtual设置为true.您还必须确保它具有该标志IsNewSlot = true,以确保它在虚方法表中有一个新插槽.
现在,对于重写的方法,您要生成:
public override void f(int);
Run Code Online (Sandbox Code Playgroud)
要做到这一点,你还需要有方法IsVirtual,但也要告诉它它不是一个新的虚方法,但是它隐含地覆盖了另一个,所以你必须要做到.IsReuseSlot = true.
而且因为你使用隐式覆盖,你还必须确保两种方法都是.IsHideBySig = true.
有了这一切,你应该有一个适当的重写方法.
为了其他读者的利益,这是通过以下JB的答案获得的最终结果:
void CreateMethodOverride(TypeDefinition targetType,
TypeDefinition baseClass, string methodName, MethodInfo methodInfo)
{
MethodDefinition baseMethod = baseClass
.Methods.First(method => method.Name.Equals(methodName));
MethodDefinition newMethod = targetType.Copy(methodInfo);
newMethod.Name = baseMethod.Name;
// Remove the 'NewSlot' attribute
newMethod.Attributes = baseMethod.Attributes & ~MethodAttributes.NewSlot;
// Add the 'ReuseSlot' attribute
newMethod.Attributes |= MethodAttributes.ReuseSlot;
newMethod.ImplAttributes = baseMethod.ImplAttributes;
newMethod.SemanticsAttributes = baseMethod.SemanticsAttributes;
targetType.Methods.Add(newMethod);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1879 次 |
| 最近记录: |