[英]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.