簡體   English   中英

事件內部:在.net中,事件如何在內部表示?

[英]Events Internals: In .net how are Events represented internally?

我有一個基本的疑問。 內部如何將事件表示為方法或(字段)對象。 如果event是一個字段,那么如何在接口定義中仍然包含事件。

謝謝JeeZ

如果你輸入:

public event EventHandler MyEvent;

編譯器生成的是(簡化)這個:

// declares a normal delegate of type 'EventHandler'
private EventHandler _myEvent;

// declares 'add_MyEvent' and 'remove_MyEvent' methods similar to a property
public event EventHandler MyEvent {
    add { _myEvent += value; }
    remove { _myEvent -= value; }
}

事件類似於財產; 圍繞委托的包裝器,只允許添加或刪除方法。 這樣您就無法完全重新分配代理並刪除其他人的訂閱。

在接口中指定事件時,您所做的就是任何實現類都應該具有事件的addremove方法。 事實上,非常類似於在接口上聲明屬性。

這也是為什么你只能在聲明它的類中調用或重新分配事件的原因 - 對類中MyEvent事件的任何引用都被重新路由以直接使用委托,而在類之外你只能訪問addremove方法,而不是直接委托。

@ thecoop的答案是對“類似場地的事件”的非常好的描述(注意“簡化”警告) - 但請注意,實際上事件可以以任何你喜歡的方式實現。 所有事件定義都是一個add / remove訪問器對(這就是為什么它可以在接口上定義,就像屬性一樣)。

例如,對於sparce事件,以下情況可能很常見:

private static readonly object FooKey = new object(), BarKey = new object();

public event EventHandler Foo {
    add {Events.AddHandler(FooKey, value);}
    remove {Events.RemoveHandler(FooKey, value);}
}
public event MouseClickEventHandler Bar {
    add {Events.AddHandler(BarKey, value);}
    remove {Events.RemoveHandler(BarKey, value);}
}

其中Events是一個EventHandlerList ,通常是延遲加載的:

private EventHandlerList events;
protected EventHandlerList Events {
    get {
        if(events == null) events = new EventHandlerList();
        return events;
    }
}

或者你可以做任何你喜歡的事情。 在合理范圍內(注意事件訂閱和委托相等/復合委托的預期行為)。

事件不表示為字段或方法。 就類的元數據而言,它們只是事件。

類似地,屬性具有特殊標志(盡管這些標志存儲為具有眾所周知名稱的方法)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM