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