我有下面的類,它有一個公共事件調用LengthChanged
:如何引用在C#中的事件
class Dimension
{
public int Length
{
get
{
return this.length;
}
set
{
if (this.length != value)
{
this.length = value;
this.OnLengthChanged();
}
}
protected virtual void OnLengthChanged()
{
var handler = this.LengthChanged;
if (handler != null)
{
handler (this, System.EventArgs.Empty);
}
}
public event System.EventHandler LengthChanged;
private int length;
}
我希望能夠爲這個事件的方法稱爲Observer
/註銷處理程序,它對Dimension
課程一無所知。我已經提出了兩個方案,其中沒有一個是真正的滿足:
定義的接口
ILengthChanged
與LengthChanged
事件,然後確保Dimension
實現ILengthChanged
。然後,我必須爲我定義的每個接口提供一個Observer
方法的實現。這絕不夠通用。我真的希望能夠簡單地傳遞對System.EventHandler
事件的引用。使用
System.Action<System.EventHandler>
回調在Observer
方法註冊和註銷事件處理程序,就像這樣:類Foo { 公共無效觀察員(System.Action寄存器, System.Action註銷) { register(this.MyEventHandler);
// keep track of the unregister callback, so that we can unregister // our event handler later on, if needed... } private void MyEventHandler(object sender, System.EventArgs e) { ... }
}
其隨後將被調用這樣的:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x);
和在被執行時,確實將結束與內部事件處理程序MyEventHandler
佈線LengthChanged
事件。但這不是很優雅。我會喜歡能夠寫這個代替:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (dim.LengthChanged);
但我不知道如何實現這一目標。也許我錯過了這裏真正明顯的東西?我猜想一些dynamic
魔法可以做到這一點,但不會強制執行編譯時類型檢查:我不希望Observer
的用戶通過引用不符合System.EventHandler
事件簽名的事件。
如果人們像埃裏克·梅傑沒能拿出更清潔的解決方案,我懷疑事實上,沒有其他辦法可以做到這一點。很傷心......謝謝你的快速回復,Jon。 – 2011-01-21 09:09:48