是否可以实现 C# 接口并扩展事件的参数
本文关键字:扩展 事件 参数 接口 实现 是否 | 更新日期: 2023-09-27 18:33:59
假设我有以下接口:
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;
}
但是,如果需要PageChanged
用于其他目的,则不能在没有泛型类型的情况下使用IBook
。
另一种方法是保持event EventHandler<EventArgs> PageChanged;
让百科全书实现传递一个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
{
}
}
}