2011-10-27 3 views
1

DynamicMethod를 사용하면 만든 대리인의 대상 인스턴스를 지정할 수 있습니다. 그러나 구조체 형식을 사용할 때이 작동하지 않는 것으로 나타납니다. 이 메서드에 바인딩 할 수 없다는 예외가있어 실패합니다. IL이 대상 인스턴스를 unbox하지 않기 때문에 오류가 있습니까?DynamicMethod를 struct 인스턴스에 바인딩 할 수없는 이유는 무엇입니까?

여기서 A를 클래스로 변경하면 문제없이 작동합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

struct A { } 
... //then some where in code:: 
Func<Type> f = CodeGen.CreateDelegate<Func<Type>>(il=> 
    il.ldarga_s(0) 
    .constrained(typeof(A)) 
    .callvirt(typeof(object).GetMethod("GetType")) 
    .ret(), 
    name:"Constrained", 
    target:new A() 
); 

참고 : 나는 유창 인터페이스의 Emitted 라이브러리를 사용하고 여기

이 샘플 생식이다 (또한 대상 인스턴스로 GetType을 방법에 바인딩 Delegate.CreateDelegate를 호출하지 않는 것이 좋습니다하시기 바랍니다) 일리노이. CodeGen Method의 코드는 다음과 같습니다.

public static class CodeGen 
{ 
    public static TDelegate CreateDelegate<TDelegate>(Action<ILGenerator> genFunc, string name = "", object target = null, bool restrictedSkipVisibility = false) 
     where TDelegate:class 
    { 
     ArgumentValidator.AssertGenericIsDelegateType(() => typeof(TDelegate)); 
     ArgumentValidator.AssertIsNotNull(() => genFunc); 

     var invokeMethod = typeof(TDelegate).GetMethod("Invoke"); 
     var @params = invokeMethod.GetParameters(); 
     var paramTypes = new Type[@params.Length + 1]; 
     paramTypes[0] = target == null ? typeof(object) : target.GetType(); 
     @params.ConvertAll(p => p.ParameterType) 
      .CopyTo(paramTypes, 1); 
     var method = new DynamicMethod(name ?? string.Empty, invokeMethod.ReturnType, paramTypes, restrictedSkipVisibility); 
     genFunc(method.GetILGenerator()); 

     return method.CreateDelegate<TDelegate>(target); 
    } 
} 

답변

0

도 여기에 적용되는, http://msdn.microsoft.com/en-us/library/74x8f551.aspx에서 중요한 참고 사항을 참조하십시오 :

방법은 정적 인 경우 (Visual Basic의 경우 Shared)와 첫 번째 매개 변수 는 Object 유형 또는 치형의 다음 firstArgument 수있다

값이 일 수 있습니다. 이 경우 firstArgument는 자동으로 boxed됩니다. 자동 C# 또는 Visual Basic 함수 호출 에서처럼 다른 인수에 대해서는 복싱이 발생하지 않습니다.

함축 된 의미는 동적 메서드의 첫 번째 인수 유형 object 될 필요가있을 것이다, 그리고 당신이 제한된 전화를하기 전에 언 박스 뒤에 ldarg_0을 수행해야한다는 것입니다.