簡體   English   中英

是否可以實現C#接口並擴展事件的參數?

[英]Is it possible to implement a C# Interface and extend the arguments of Events?

假設我有以下界面:

interface IBook
{
    event EventHandler<EventArgs> PageChanged;
}

我可以在本課程中輕松實現:

class Novel : IBook
{
    public event EventHandler<EventArgs> PageChanged;

    protected void OnPageChanged()
    {
        EventHandler<EventArgs> pageChanged = PageChanged;
        if (pageChanged != null) pageChanged(this, EventArgs.Empty);
    }
}

但是,如果我現在有一個稱為Encyclopedia的對象定義為:

class Encyclopedia : IBook
{
    public class EncyclopediaEventArgs : EventArgs
    {
        public int Volume
        {
            get { return volume; }
        }

        private int volume;

        public EncyclopediaEventArgs(int volume)
        {
            this.volume = volume;
        }
    }

    public event EventHandler<EncyclopediaEventArgs> PageChanged;

    protected void OnPageChanged(int volume)
    {
        EventHandler<EncyclopediaEventArgs> pageChanged = PageChanged;
        if (pageChanged != null) pageChanged(this, new EncyclopediaEventArgs(volume));
    }
}

它具有Book所有功能,但具有Volume的添加的事件參數字段。 當我編譯時,我得到一個錯誤(我猜想是這樣):

錯誤CS0738:“百科全書庫”未實現接口成員“ IBook.PageChanged”。 'Encyclopedia.PageChanged'無法實現'IBook.PageChanged',因為它沒有匹配的返回類型'System.EventHandler'

它聲明它不能實現IBook.PageChanged因為System.EventHandler<System.EventArgs>不是返回類型,即使EncyclopediaEventArgs派生自System.EventArgs

因此,我的問題是,是否有可能派生出諸如Encyclopedia類的類,該類將附加的Volume字段添加到其事件參數中?

(關於為什么這是一個糟糕的設計/體系結構決定,任何討論都非常受歡迎!)

這樣做似乎很簡單:

interface IBook<T> where T : EventArgs
{
    event EventHandler<T> PageChanged;
}

class Novel : IBook<EventArgs> { ... }

class Encyclopedia : IBook<Encyclopedia.EncyclopediaEventArgs> { ... }

如果您仍然需要普通的IBook則可以執行以下操作:

interface IBook { }

interface IBook<T> : IBook where T : EventArgs
{
    event EventHandler<T> PageChanged;
}

這取決於您將如何使用IBook 您可以像這樣為EventArgs創建通用參數:

public interface IBook<TEventArgs> where TEventArgs : EventArgs
{
    event EventHandler<TEventArgs> PageChanged;
}

public class Novel : IBook<EventArgs>
{
    event EventHandler<EventArgs> PageChanged;
}

public class Encyclopedia : IBook<EncyclopediaEventArgs>
{
    event EventHandler<EncyclopediaEventArgs> PageChanged;
}

但你不能使用IBook沒有泛型類型,如果你需要PageChanged用於其他目的。

另一種方法是只保留event EventHandler<EventArgs> PageChanged; 讓Encyclopedia實現傳遞一個EncyclopediaEventArgs並將其強制轉換為事件處理程序。

class Encyclopedia : IBook
{
    public class EncyclopediaEventArgs : EventArgs
    {
    }

    public event EventHandler<EventArgs> PageChanged;

    protected void OnPageChanged(int volume)
    {
        EventHandler<EventArgs> pageChanged = PageChanged;
        if (pageChanged != null) pageChanged(this, new EncyclopediaEventArgs(...));
    }
}

public class BookReader
{
    public void OnPageChanged(object sender, EventArgs e)
    {
        if (sender is Encyclopedia && e is EncyclopediaEventArgs)
        {
            EncyclopediaEventArgs ee = (EncyclopediaEventArgs)e;
        }
        else
        {
        }
    }
}

暫無
暫無

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

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