2015-10-04 25 views
1

我的問題是,如果我可以確定事件的名稱通過EventHandler類型的參數傳遞?隨着一些代碼變得更加清晰:從EventHandler確定事件名稱<T>在C#

public void RaiseEvent<T>(EventHandler<T> eventToRaise, T args) where T : EventArgs, IXmlConvertable 
    { 
     Log(eventToRaise.Method.Name, args.ToXElement()); 
     ThreadPool.QueueUserWorkItem((e) => eventToRaise(this, args)); 
    } 

public event EventHandler<ProductLeftEventArgs> ProductLeftEvent = delegate { }; 

正如你可以看到,我想創建,不僅調用了事件的異步的方法,同時也記錄了行動。 IXmlConvertable是一個自定義接口,用於記錄。我打電話的方式是這樣的:

this.RaiseEvent(this.ProductLeftEvent, new ProductLeftEventArgs() { ... }); 

我想獲得的是一個帶有「ProductLeftEvent」的字符串。不幸的是,eventToRaise.Method.Name給出了字符串「DeliverEvent」。你認爲有可能實現這個名字嗎?另外值得一提的是,我在分配處理程序時使用了弱事件管理器。

+0

什麼是'DeliverEvent'?它與你發佈的代碼有什麼關係? –

+0

這是一個很好的問題。我不知道。我唯一知道的就是'eventToRaise.Method.Name'屬性的值。 –

回答

1

eventToRise參數是一個委託 - 即對方法(以及應該調用該方法的目標或對象)的引用。事件持有對訂閱該事件的所有方法的引用。

所以你的情況看來,「使用deliverEvent」是被連接到您的活動在這樣的應用程序的其它部分的方法:someObject.ProductLeftEvent += this.DeliverEvent;

如果你真的想事件本身傳遞給RaiseEvent方法你要麼需要使用表達式,要麼只需傳遞一個eventName(但這將是一種重複)。

下面是如何使用表達式來做到這一點的例子:

public void RaiseEvent<T>(Expression<Func<EventHandler<T>>> eventToRaise, T args) where T : EventArgs, IXmlConvertable 
{ 
    string eventName = ((MemberExpression)eventToRaise.Body).Member.Name; 
    Log(eventName, args.ToXElement()); 
    EventHandler<T> eventHandler = eventToRaise.Compile()(); 
    ThreadPool.QueueUserWorkItem((e) => eventHandler(this, args)); 
} 

你會調用這個方法是這樣的:

this.RaiseEvent(() => this.ProductLeftEvent, new ProductLeftEventArgs() { ... }); 
+0

@Attila Szobonya:讓我知道它是否有幫助。 – Vova

+0

對不起,花了這麼長時間。我試過你的代碼,它確實是我想要的。我認爲這是一個非常聰明的解決方案。標記爲答案。謝謝。 :) –

相關問題