2010-07-13 3 views
1

Я использую Mono.Cecil (версия 0.6.9.0) для псевдонима метода, который реализует метод интерфейса. Чтобы сделать это, я должен добавить Override к целевому методу, который указывает назад к методу интерфейса (так же, как то, что возможно с VB.NET), как это:Как реализовать метод интерфейса с помощью Mono.Cecil?

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() { } 
} 

Что я получаю это PEVerify.exe ошибка, указывающая на то, что мой класс больше не реализует метод интерфейса. Кажется, что есть маркер несоответствие в измененной сборке между ссылкой переназначения и методой в интерфейсе:

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

Я знаю, что если я использую MethodDefinition непосредственно он будет работать:

targetMethod.Overrides.Add(sourceMethod); 

Но Мне действительно нужно использовать MethodReference, потому что у меня могут быть общие параметры и аргументы в используемых типах, и простой MethodDefinition не будет делать.

Обновление: Как рекомендовано Jb Evain, у меня есть migrated до версии 0.9.3.0. Но такая же ошибка все же происходит. Вот перенесенный код:

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); 

ответ

3

Это одна из неприятностей использования 0,6. Вы должны поместить вновь созданную MethodReference в коллекцию .MemberReferences вашего модуля.

Я настоятельно рекомендую вам перейти на 0,9.

+0

Большое спасибо, но я тоже пробовал, и это не сработало. –

+0

Я только что перенес его, и я получаю ту же ошибку. Я уточню вопрос. –

+0

Странно, я буду исследовать. –

Смежные вопросы