2013-03-18 69 views
1

作爲我的問題here的後續,我試圖創建一個匿名事件處理程序,其參數在運行時決定。Lambda表達式或具有運行時參數的委託

private void RegisterEventHandlers(Control ctl) 
{ 
    foreach (Command command in CommandList) 
    { 
    EventInfo eventInfo = ctl.GetType().GetEvent(command.Name); 

    List<ParameterExpression> callArguments = new List<ParameterExpression>(); 
    foreach (ParameterInfo parameter in eventInfo.EventHandlerType.GetMethod("Invoke").GetParameters()) 
    { 
     callArguments.Add(Expression.Parameter(parameter.ParameterType, parameter.Name)); 
    } 

    //begin pseudo code 
    method = (callArguments) => 
    { 
     if (sender != null) ... 
     if (e != null) ... 
     name = command.name; 
    }; 
    or 
    method = new delegate 
    { 
     if (sender != null) ... 
     if (e != null) ... 
     name = command.name; 
    }; 
    //end pseudo code 

    var body = Expression.Call(Expression.Constant(this), method, callArguments); 
    var lambda = Expression.Lambda(eventInfo.EventHandlerType, body, callArguments); 

    eventInfo.AddEventHandler(ctl, lambda.Compile()); 
    } 
} 

我發現我的lambda表達式和委託太多缺乏解決這一問題的認識......

匿名處理程序必須做無非轉發發送者對象,事件參數和命令對象另一個功能。並不是所有的事件都有相同的參數,因此我的想法是將處理程序定義爲具有動態參數的匿名函數。

然而,其他可能解決我的問題的解決方案是最受歡迎的。

+0

這裏有一個相關的鏈接,只是爲了讓你自己瞭解一下你自己進入的內容:http://stackoverflow.com/questions/12865848/general-purpose-fromevent-method – Servy 2013-03-18 13:59:41

+0

有趣的例子,但地獄的維護。感謝分享:) – 2013-03-29 12:04:20

回答

0

可以聲明委託/λ爲取一個參數數組:

method = delegate(params object[] args) 
{ 
    ... 
}; 

和裏面,使用MethodInfo的類來獲取有關該參數應該被轉發方法的信息。

但我認爲你在這裏過於活躍。 Reflection允許您繞過使用編譯時功能時所需的常規抽象機制。這會導致複雜性,可讀性的損失,並且會將很多編譯時錯誤轉化爲運行時錯誤。您仍然可以在運行時使用多態性和委託來決定東西,同時保持可讀性和編譯時類型安全性。微軟在他們的庫中完成了這一切。除了System.Reflection名稱空間的實際實現外,您從不會看到需要使用反射的庫。

+0

我最終決定我不需要這個。爲發件人解決,EventArgs模式足夠好。謝謝 – 2013-03-29 13:14:54