c#如何实现接口事件
作者:olprod 时间:2023-10-02 18:31:28
接口可以声明事件。 下面的示例演示如何在类中实现接口事件。 这些规则基本上都与实现任何接口方法或属性时的相同。
在类中实现接口事件
在类中声明事件,然后在相应区域中调用它。
namespace ImplementInterfaceEvents
{
public interface IDrawingObject
{
event EventHandler ShapeChanged;
}
public class MyEventArgs : EventArgs
{
// class members
}
public class Shape : IDrawingObject
{
public event EventHandler ShapeChanged;
void ChangeShape()
{
// Do something here before the event…
OnShapeChanged(new MyEventArgs(/*arguments*/));
// or do something here after the event.
}
protected virtual void OnShapeChanged(MyEventArgs e)
{
ShapeChanged?.Invoke(this, e);
}
}
}
示例
下面的示例演示如何处理不太常见的情况:类继承自两个或多个接口,且每个接口都具有相同名称的事件。 在这种情况下,你必须为至少其中一个事件提供显式接口实现。 为事件编写显式接口实现时,还必须编写 add
和 remove
事件访问器。 通常这些访问器由编译器提供,但在这种情况下编译器不提供它们。
通过提供自己的访问器,可以指定两个事件是由类中的同一个事件表示,还是由不同事件表示。 例如,如果根据接口规范应在不同时间引发事件,可以在类中将每个事件与单独实现关联。 在下面的示例中,订阅服务器确定它们通过将形状引用转换为 IShape
或 IDrawingObject
接收哪个 OnDraw
事件。
namespace WrapTwoInterfaceEvents
{
using System;
public interface IDrawingObject
{
// Raise this event before drawing
// the object.
event EventHandler OnDraw;
}
public interface IShape
{
// Raise this event after drawing
// the shape.
event EventHandler OnDraw;
}
// Base class event publisher inherits two
// interfaces, each with an OnDraw event
public class Shape : IDrawingObject, IShape
{
// Create an event for each interface event
event EventHandler PreDrawEvent;
event EventHandler PostDrawEvent;
object objectLock = new Object();
// Explicit interface implementation required.
// Associate IDrawingObject's event with
// PreDrawEvent
#region IDrawingObjectOnDraw
event EventHandler IDrawingObject.OnDraw
{
add
{
lock (objectLock)
{
PreDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PreDrawEvent -= value;
}
}
}
#endregion
// Explicit interface implementation required.
// Associate IShape's event with
// PostDrawEvent
event EventHandler IShape.OnDraw
{
add
{
lock (objectLock)
{
PostDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PostDrawEvent -= value;
}
}
}
// For the sake of simplicity this one method
// implements both interfaces.
public void Draw()
{
// Raise IDrawingObject's event before the object is drawn.
PreDrawEvent?.Invoke(this, EventArgs.Empty);
Console.WriteLine("Drawing a shape.");
// Raise IShape's event after the object is drawn.
PostDrawEvent?.Invoke(this, EventArgs.Empty);
}
}
public class Subscriber1
{
// References the shape object as an IDrawingObject
public Subscriber1(Shape shape)
{
IDrawingObject d = (IDrawingObject)shape;
d.OnDraw += d_OnDraw;
}
void d_OnDraw(object sender, EventArgs e)
{
Console.WriteLine("Sub1 receives the IDrawingObject event.");
}
}
// References the shape object as an IShape
public class Subscriber2
{
public Subscriber2(Shape shape)
{
IShape d = (IShape)shape;
d.OnDraw += d_OnDraw;
}
void d_OnDraw(object sender, EventArgs e)
{
Console.WriteLine("Sub2 receives the IShape event.");
}
}
public class Program
{
static void Main(string[] args)
{
Shape shape = new Shape();
Subscriber1 sub = new Subscriber1(shape);
Subscriber2 sub2 = new Subscriber2(shape);
shape.Draw();
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
}
/* Output:
Sub1 receives the IDrawingObject event.
Drawing a shape.
Sub2 receives the IShape event.
*/
来源:https://github.com/dotnet/docs.zh-cn/blob/live/docs/csharp/programming-guide/events/how-to-implement-interface-events.md
标签:c#,接口,事件
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
java随机生成8位数授权码的实例
2022-04-24 12:03:47
winfrom 在业务层实现事务控制的小例子
2021-11-16 14:19:50
SpringBoot整合Apollo配置中心快速使用详解
2022-12-25 17:00:34
![](https://img.aspxhome.com/file/2023/7/61337_0s.jpg)
Android自定义控件实现滑动开关效果
2022-10-25 00:45:39
![](https://img.aspxhome.com/file/2023/4/138004_0s.gif)
浅谈SpringBoot资源初始化加载的几种方式
2022-03-09 08:14:34
![](https://img.aspxhome.com/file/2023/3/80253_0s.jpg)
Java实战之实现一个好用的MybatisPlus代码生成器
2023-06-18 02:16:10
![](https://img.aspxhome.com/file/2023/8/57498_0s.png)
java实现两个对象之间传值及简单的封装
2022-03-11 13:53:18
![](https://img.aspxhome.com/file/2023/3/132083_0s.jpg)
IDEA中Mybatis的MGB使用逆向工程配置的详细教程
2022-01-04 17:19:50
![](https://img.aspxhome.com/file/2023/3/88583_0s.png)
浅谈java中的重载和重写的区别
2023-03-31 04:45:57
![](https://img.aspxhome.com/file/2023/6/75516_0s.png)
C#中Timer使用及解决重入问题
2022-02-21 00:44:52
![](https://img.aspxhome.com/file/2023/6/102186_0s.png)
springboot实现基于aop的切面日志
2022-09-09 11:53:11
带你了解C++的数组与函数
2023-12-10 20:44:18
![](https://img.aspxhome.com/file/2023/6/127516_0s.jpg)
Android编程实现为ListView创建上下文菜单(ContextMenu)的方法
2021-12-09 06:26:28
Android开发新手常见的10个误区
2021-07-30 02:14:10
Hibernate的一对一,一对多/多对一关联保存的实现
2022-03-13 12:41:08
Java中的内存泄露问题和解决办法
2022-05-12 20:02:35
![](https://img.aspxhome.com/file/2023/4/84194_0s.png)
深入java垃圾回收的详解
2021-11-19 10:33:06
Android中FoldingLayout折叠布局的用法及实战全攻略
2021-05-23 19:29:17
![](https://img.aspxhome.com/file/2023/9/137149_0s.jpg)
Unity实现弹球打砖块游戏
2021-09-24 16:13:08
![](https://img.aspxhome.com/file/2023/9/104349_0s.jpg)
Java算法实战之排一亿个随机数
2022-11-22 02:47:26
![](https://img.aspxhome.com/file/2023/4/60694_0s.png)