简体   繁体   English

如何使用Mono.Cecil为接口方法实现添加别名?

[英]How to alias an interface method implementation with Mono.Cecil?

I'm using Mono.Cecil (version 0.6.9.0) to alias a method that implements an interface method. 我正在使用Mono.Cecil (版本0.6.9.0)为实现接口方法的方法添加别名。 To do that, I have to add an Override to the target method that points back to the interface method (much like what's possible with VB.NET), like this: 为此,我必须向目标方法添加一个Override以指向接口方法(类似于VB.NET的实现),如下所示:

using System;
using System.Reflection;
using Mono.Cecil;

class Program {

  static void Main(string[] args) {
    var asm = AssemblyFactory.GetAssembly(Assembly.GetExecutingAssembly().Location);

    var source = asm.MainModule.Types["A"];
    var sourceMethod = source.Methods[0];
    var sourceRef = new MethodReference(
      sourceMethod.Name,
      sourceMethod.DeclaringType,
      sourceMethod.ReturnType.ReturnType,
      sourceMethod.HasThis,
      sourceMethod.ExplicitThis,
      sourceMethod.CallingConvention);

    var target = asm.MainModule.Types["C"];
    var targetMethod = target.Methods[0];
    targetMethod.Name = "AliasedMethod";
    targetMethod.Overrides.Add(sourceRef);

    AssemblyAssert.Verify(asm); // this will just run PEVerify on the changed assembly
  }

}

interface A {
  void Method();
}

class C : A {
  public void Method() { }
}

What I'm getting is a PEVerify.exe error that indicates that my class doesn't implement the interface method anymore. 我得到的是一个PEVerify.exe错误,该错误指示我的类不再实现接口方法。 It seems that there's a token mismatch in the changed assembly between the override reference and the method in the interface: 似乎在覆盖的引用和接口中的方法之间的更改程序集中存在令牌不匹配:

[MD]: Error: Class implements interface but not method (class:0x02000004; interface:0x02000002; method:0x06000001). [token:0x09000001]

I know that if I use the MethodDefinition directly it will work: 我知道,如果我直接使用MethodDefinition ,它将起作用:

targetMethod.Overrides.Add(sourceMethod);

But I really need to use a MethodReference because I might have generic parameters and arguments in the types involved, and a simple MethodDefinition won't do. 但是我确实需要使用MethodReference因为我可能在所涉及的类型中具有通用的参数和参数,而简单的MethodDefinition则不会。

Update : As recommended by Jb Evain , I've migrated to version 0.9.3.0. 更新 :按照Jb Evain的建议,我已经迁移到0.9.3.0版。 But, the same error still happens. 但是,同样的错误仍然发生。 Here's the migrated code: 这是迁移的代码:

var module = ModuleDefinition.ReadModule(Assembly.GetExecutingAssembly().Location);

var source = module.GetType("A");
var sourceMethod = source.Methods[0];

var sourceRef = new MethodReference(
  sourceMethod.Name,
  sourceMethod.ReturnType) {
    DeclaringType = sourceMethod.DeclaringType,
    HasThis = sourceMethod.HasThis,
    ExplicitThis = sourceMethod.ExplicitThis,
    CallingConvention = sourceMethod.CallingConvention 
};

var target = module.GetType("C");
var targetMethod = target.Methods[0];
targetMethod.Name = "AliasedMethod";
targetMethod.Overrides.Add(sourceRef);

That's one of the annoyance of using the 0.6. 这是使用0.6的烦恼之一。 You have to put the newly created MethodReference in the .MemberReferences collection of your module. 您必须将新创建的MethodReference放入模块的.MemberReferences集合中。

I strongly suggest you switch to 0.9. 我强烈建议您切换到0.9。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM