2010-07-13 3 views
1

Mono.Cecil (버전 0.6.9.0)을 사용하여 인터페이스 메소드를 구현하는 메소드의 별명을 지정합니다. 이런 식으로, 나는 (많은 VB.NET으로 무엇이 가능한지 등) 인터페이스 메서드에 다시 가리키는 대상 방법에 Override을 추가 할 수 있고, 그렇게하려면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

이상한, 조사하겠습니다. –

관련 문제