簡體   English   中英

在派生類C#中引發基類事件

[英]Raise Base Class Events in Derived Classes C#

我有一個基類DockedToolWindow:Form,還有許多從DockedToolWindow派生的類。 我有一個容器類,用於保存事件並將事件分配給DockedToolWindow對象,但是我想從子類中調用事件。

實際上,我對如何實現此MSDN網站告訴我的事情有疑問。 下面的這一節給了我這個問題:

    // The event. Note that by using the generic EventHandler<T> event type
    // we do not need to declare a separate delegate type.
    public event EventHandler<ShapeEventArgs> ShapeChanged;

    public abstract void Draw();

    //The event-invoking method that derived classes can override.
    protected virtual void OnShapeChanged(ShapeEventArgs e)
    {
        // Make a temporary copy of the event to avoid possibility of
        // a race condition if the last subscriber unsubscribes
        // immediately after the null check and before the event is raised.
        EventHandler<ShapeEventArgs> handler = ShapeChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

當然,此示例可以編譯並運行,但是當我將“ ShapeChanged”替換為“ Move”(從Form派生而來的事件)時,錯誤地提示我不能在沒有+ =或-=的情況下在右側移動。 我還刪除了ShapeEventArgs通用標簽。

有人煽動為什么這行不通嗎? 類中聲明的事件與繼承的事件之間有什么區別?

您不能直接觸發基類事件。 這就是為什么必須將OnShapeChanged方法protectedprivate方法的原因。

使用base.OnMove()代替。

從C#語言規范的10.7節(添加了重點):

在包含事件聲明的類或結構的程序文本中,某些事件可以像fields一樣使用 要以這種方式使用,事件不得為抽象事件或外部事件,並且不得明確包含event-accessor-declaration。 這樣的事件可以在允許字段的任何上下文中使用。 該字段包含一個委托(§15),該委托引用已添加到事件的事件處理程序的列表。 如果未添加事件處理程序,則該字段包含null。

因此,您不能將Move事件視為一個字段,原因是它以不同的類型(在本例中為您的超類)定義。 我同意@womp的推測,即設計師做出此選擇是為了防止意外出現在活動中。 允許無關的類型(不是從聲明事件的類型派生的類型)執行此操作顯然很糟糕,但是即使對於派生類型,也可能不希望這樣做。 他們可能必須包含語法,以允許將事件聲明設為privateprotected字段樣式使用的保護,因此我的猜測是他們選擇完全禁止這樣做。

區別在於范圍。 在您的類內部,您可以控制事件委托的處理方式,但是,您的類無法控制基類的工作。 它可能會對事件及其處理程序進行一些瘋狂的幕后操作。 如果您只是“重新分配”了Move事件,則將清除該事件的多播委托列表。

我猜想他們對此施加了編譯器限制,因為這是一種非常不安全的做法,並且實際上將使任何后代類都有能力破壞其父級的事件模型。

您只需要在定義事件本身的類中發布的代碼。 所有派生類都應直接調用OnShapeChanged()或OnMove(),而不進行復制等操作,因此,您根本不應在類中編寫該代碼(因為Move事件是在基類中定義的)。

如果確實需要在派生類中進行某種處理(也許您需要弄弄集合類?),則可以覆蓋虛擬的OnXXX調用,並在調用base.OnXXX()之前進行填充。 在MSDN文章中,Circle類對應於您的DockedToolWindow類。 您的派生類應該可以使用相同的模式。

暫無
暫無

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

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