2012-05-24 63 views
1

我有一個函數:通行證表達式樹的方法參數

public void Execute(Expression<Action> expression) 
{ 
    var time = expression.Compile().Benchmark(); 

    var msg = string.Format("{0} took {1} to complete", 
     ReflectionHelper.GetComponentCallDetails().ToString(), 
     time.ToString(@"hh\:mm\:ss\.ff")); 

    Logger.Info(msg); 
} 

需要被調用的委託是這樣的:

channels = GetAllChannelsImpl(maxResults); 

我是比較新的表達式樹和想不通一種將Action委託傳遞給方法的方法。

我是能夠做到使用

public void Execute(Action action) 
{ 
    var time = action.Benchmark(); 

    var msg = string.Format("{0} took {1} to complete", 
     ReflectionHelper.GetComponentCallDetails().ToString(), 
     time.ToString(@"hh\:mm\:ss\.ff")); 

    Logger.Info(msg); 
} 

,並調用相同的功能

Execute(() => 
{ 
    channels = GetAllChannelsImpl(maxResults); 
}); 

但我想用表達式樹爲基礎的方法,以消除需要使用開銷通過反射來找出調用記錄方法的細節。

任何人都可以提出正確的方法來傳遞上述操作委託的表達式樹作爲方法參數。

+0

您已經重載了'Execute()'方法 - 因此編譯器將'Action'版本優先於'Expression '版本。如果不是這種情況,調用語法可以是相同的。你嘗試過新的表達式(()=> //等)嗎?它應該是直截了當的。 – Jonno

回答

2

lambda表達式本身沒有類型。它需要的實際類型由編譯器根據您要分配或轉換的內容推斷出來。因此,使用簡單lambda表達式對您的Execute()方法進行的任何調用都將不明確,因爲您的lambda表達式將兼容爲ActionExpression<Action>。您必須通過明確轉換爲您所期望的類型來消除歧義。

// assign to a variable 
Expression<Action> action1 =() => ...; 
Execute(action1); 

// cast 
Execute((Expression<Action>)(() => ...)); 

// use the constructor 
Execute(new Expression<Action>(() => ...)); 

這將是更好的恕我直言,以消除模糊超載和重命名其中一種方法。我建議將表情重載重命名爲ExecuteExpression()