2013-09-26 1 views
1

컴파일 된 표현식 만들기를 호출 할 때 결과로 컴파일 된 대리자에서 CreateDelegate를 호출하려고하지만 설명이있는 NotSupportedException을 찾습니다. 파생 클래스가 구현을 제공해야합니다. 컴파일 된 메서드에 대한 대리자는 어떻게 만듭니 까?CreateDelegate 파생 클래스가 구현을 제공해야합니다.

public delegate int AddOne(int input); 

void Main() 
{ 
    var input = Expression.Parameter(typeof(int)); 
    var add = Expression.Add(input,Expression.Constant(1)); 
    var lambda = Expression.Lambda(typeof(AddOne),add,input); 
    var compiled = (AddOne)lambda.Compile(); 
    compiled.Method.CreateDelegate(typeof(AddOne)); 
} 
+0

아직 실제입니다. 또한, 컴파일 된 델리게이트의 MethodInfo를 가져 와서 내 strucutres에 저장 한 다음 다시 호출하도록 MethodInfo를 "다시 캐스팅"해야합니다. 이 코드는 제대로 작동하지만 작동하지 않아야하며 '파생 클래스가 구현을 제공해야 함'오류가 분명하지 않습니다. –

답변

3

CreateDelegate으로 전화 할 필요가 없습니다. lambda.Compile에서 AddOne으로 결과를 캐스팅하는 것이 전부였습니다.

관찰 : 성공적 유형 AddOne의 대리자를 받아들이는 Test 메소드를 호출 할 수 있습니다

public delegate int AddOne(int input); 

public int Test(AddOne f) 
{ 
    return f(1); 
} 

void Main() 
{ 
    var input = Expression.Parameter(typeof(int)); 
    var add = Expression.Add(input,Expression.Constant(1)); 
    var lambda = Expression.Lambda(typeof(AddOne),add,input); 
    var compiled = (AddOne)lambda.Compile(); 
    Console.WriteLine(Test(compiled)); // 2 
} 

.

+0

그래서 해봤는데 잘 작동합니다. 문제는 너무 느리다는 것입니다. 성능 테스트에서 함수를 호출하는 시간의 93 %가 System.Reflection.Emit.DynamicMethod.CreateDelegate (Type, Object)에서 사용됩니다. 나는이 함수를 빡빡한 루프 안에서 여러 번 호출하기 때문에 나는 이것을 한 번 호출 할 수 있다면 매번 호출 할 필요가 없다고 생각한다. – heneryville

+0

@heneryville 한 번만'Compile '을 호출하면 오래 걸리지 않을 것입니다. 'for'-loop에서'Test (compiled)'를 호출 해 보았을 때 100000000 회 반복으로 눈금이 느려졌습니다 (~ 0.466 초). –

+0

@heneryville 질문에 대한 성과가 전혀 보이지 않습니다. * 잘 작동하면 * 받아들이지 않는 이유는 무엇입니까? –