簡體   English   中英

C#僅將事件引發到繼承的類

[英]C# Raising event to inherited classes only

我有一個通用的用戶控件:

public partial class SearchBoxGeneric<T> : UserControl
{
    protected class RecordFoundEventArgs
    {
        public T Record { get; private set; }

        public RecordFoundEventArgs(T record)
        {
            this.Record = record;
        }
    }
    protected event EventHandler<RecordFoundEventArgs> RecordFound;

    //Called from search button
    public void Find()
    {
        //1. Search for record in the db
        //2. Raise event to derived classes
    }
}

我有從該通用控件繼承的用戶控件。 現在,當我從數據庫搜索記錄時,我想將事件引發給繼承的控件。

我怎樣才能做到這一點?

要引發事件,請使用與公共事件相同的代碼:

public void Find()
{
    T record = FindRecordCore();
    if (record != default(T))
    {
        var recordFound = RecordFound;
        if (recordFound != null)
            recordFound(this, new RecordFoundEventArgs(record));
    }
}

要遵循事件的正常模式,應添加特定的OnXyz方法:

protected virtual void OnRecordFound(RecordFoundEventArgs e)
{
    var recordFound = RecordFound;
    if (recordFound != null)
        recordFound(this, e);
}

像這樣調用:

public void Find()
{
    T record = FindRecordCore();
    if (record != default(T))
        OnRecordFound(new RecordFoundEventArgs(record));
}

但是我會考慮的是,是否需要在這里舉行一個活動。 為什么不簡單地使用受保護的方法? 事件是外部類的通知(或連接點 ),派生類始終可以簡單地重寫類方法。 protected事件很奇怪 ,您應該問自己原因:

protected virtual void OnRecordFound(T record)
{
    // Derived classes will handle "event" here
}

public void Find()
{
    T record = FindRecordCore();
    if (record != default(T))
        OnRecordFound(record);
}

即使事件是public如果您遵循常規事件模式(並且您具有protected OnRecordFound方法),通常派生的類也應覆蓋OnRecordFound()並且事件RecordFound由外部實體使用。

通常會觸發事件,以便在發生事件時通知其他人。

public class SearchBox {
    public event EventHandler<RecordFoundEventArgs> RecordFound;

    protected virtual void OnRecordFound(RecordFoundEventArgs e) {
        var recordFound = RecordFound;
        if (recordFound != null) {
            recordFound(this, e);
        }
    }

    public void Find() {
        // ...

        // Fire event
        OnRecordFound(new RecordFoundEventArgs(...));
    }
}

// Usage
var searchBox = new SearchBox();
searchBox.RecordFound += (s, e) => { ... };
searchBox.Find();   // trigger the eventhandler we just defined

但是,如果您有派生類,則更常見的是重寫OnRecordFound方法,並添加在此運行所需的邏輯。

public class SpecialSearchBox: SearchBox {
    protected override void OnRecordFound(RecordFoundEventArgs e) {
        base.OnRecordFound(e);

        // Do something extra
    }
}

現在,無論何時觸發事件,派生類中的邏輯都會自動運行。

如果定義事件只是為了通知派生類,則定義一個可以從基類調用的虛擬方法可能會更容易。

暫無
暫無

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

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