2009-08-18 3 views
5

out 매개 변수를 가진 대리자에 대해 DynamicMethod를 정의하는 방법은 무엇입니까?DynamicMethod 및 out-parameters?

public delegate void TestDelegate(out Action a); 

의 나는 단순히 내가 메서드를 호출 할 때 nulla 인수를 설정하는 방법을 원하는 가정 해 봅시다.

이 처리 방법은 아마도 Action 대리자를 반환하는 것이지만이 방법은 큰 프로젝트에서 단순화 된 부분 일 뿐이며 문제의 메서드는 이미 값을 반환합니다. 따라서 out 매개 변수를 처리해야하므로 질문이 필요합니다. del(out a); 줄에

VerificationException was unhandled: 
Operation could destabilize the runtime. 

:이 얻을, 그러나

using System; 
using System.Text; 
using System.Reflection.Emit; 

namespace ConsoleApplication8 
{ 
    public class Program 
    { 
     public delegate void TestDelegate(out Action a); 

     static void Main(String[] args) 
     { 
      var method = new DynamicMethod("TestMethod", typeof(void), 
       new Type[] { typeof(Action).MakeByRefType() }); 
      var il = method.GetILGenerator(); 

      // a = null; 
      il.Emit(OpCodes.Ldnull); 
      il.Emit(OpCodes.Starg, 0); 

      // return 
      il.Emit(OpCodes.Ret); 

      var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate)); 
      Action a; 
      del(out a); 
     } 
    } 
} 

:

나는이 시도.

스택에 null을로드하고이를 인수에 저장하려고 시도하는 두 줄을 주석 처리하면 예외없이 메서드가 실행됩니다.


편집 :이 최선의 방법인가?

il.Emit(OpCodes.Ldarg_0); 
il.Emit(OpCodes.Ldnull); 
il.Emit(OpCodes.Stind_Ref); 
+0

동적 방법을 만드는 것이 정말로 필요합니까? 왜 런타임에 원하는 것을 수행하도록 구성 할 수있는 클래스에서 메소드를 구현하지 않습니까? –

+0

정말 동적 인 방법이어야합니다. 이것은 거대한 반사 기반의 호출 트리를보다 신속하게 실행하기위한 마지막 스톱 최적화 작업입니다. 지금까지 동적 메소드 접근법을 사용하는 오버 헤드는 기존 코드가 약 85 % 적게 보이고, 이것은 매 초당 수천 번 호출되는 코드입니다. 측정 결과에 따르면 상당수의 CPU가 기존 리플렉션 코드에 묶여 있음을 알 수 있습니다. –

답변

6

out 인자 파라미터에 적용된 OutAttribute와 단지 ref 인자이다.

by-ref 인수에 저장하려면 인수 자체가 객체의 실제 위치에 대한 관리되는 포인터이기 때문에 stind opcode를 사용해야합니다.

ldarg.0 
ldnull 
stind.ref