2013-09-26 78 views
1

當調用創建編譯expressiong我想打電話給createDelegate方法對所得編譯代表,但我geeting 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,將其保存在我的結構中,然後「重新投射」MethodInfo再次進行委派。這段代碼應該可以工作,但它不''和''派生類必須提供實現'的性質'錯誤尚不清楚。 –

回答

3

您無需致電CreateDelegate。將結果從lambda.Compile投射到AddOne是您所需要的。

觀察:

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 
} 

可以成功調用Test方法,它接受AddOne類型的委託。

+0

所以我已經做到了,而且工作正常。問題是它超慢。在性能測試中的調用函數的時間93%是花費在System.Reflection.Emit.DynamicMethod.CreateDelegate(類型,對象)。因爲我在一個緊密的循環中多次調用這個函數,所以我想如果我可以自己調用它,那麼每次都不需要調用它。 – heneryville

+0

@heneryville只要你只調用'編譯'一次,它不應該那麼長。我嘗試在'for'循環中調用'Test(編譯)',並且在100000000次迭代中僅顯着減慢(〜0.466秒)。 –

+0

@heneryville我沒有看到任何關於你的問題的表現。任何理由不接受*如果工作正常? –

相關問題