c#如何实现接口事件
作者:olprod 发布时间:2023-10-02 18:31:28
标签:c#,接口,事件
接口可以声明事件。 下面的示例演示如何在类中实现接口事件。 这些规则基本上都与实现任何接口方法或属性时的相同。
在类中实现接口事件
在类中声明事件,然后在相应区域中调用它。
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
0
投稿
猜你喜欢
- 1.super介绍我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。用于访问父类的属性,方法,构造器2.super
- 动态替换Spring容器中的Bean原因最近在编写单测时,发现使用 Mock 工具预定义 Service 中方法的行为特别难用,而且无法精细
- 在一次源码查看ThreadGroup的时候,看到一段代码,为以下:/* * @throws NullPointer
- JAVA是面向对象的语言,开发者在操作数据的时候,通常更习惯面对一个特定类型的对象,如一个用户就是一个User类的对象。DAO层需要做的,就
- 一、简介BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。实例化Bean做前置处理、后置处理二、接口定义
- 在jdk1.4中提出的技术,非阻塞IO,采用的是基于事件处理方式。传统的io技术为阻塞的,比如读一个文件,惹read方法是阻塞的,直到有数据
- android 实现拨打电话的app,代码非常简单,功能也很实用,分享给大家。MainActivity.javapackage com.bb
- Java非法字符: ‘\ufeff‘Java中项目启动出现 非法字符: '\ufeff
- 前言假设项目打包后,项目结构为:此时如果需要再windows环境中进行项目的启动或关闭,需要频繁的手敲命令,很不方便。此时可以编写.bat脚
- Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)用户线程即运行在前台的线程,而守护线程是运行
- 有时候,我们在同一个activity里面有很多fragment,在横竖屏的时候,有些fragment要求重新加载数据,有些不需要,如何简单控
- 导语相信大家无论是做前端还是做后端的,都被接口接口文档所折磨过,前端抱怨接口文档和后端给的不一致,后端抱怨写接口文档很麻烦,所以Swagge
- 前言前面介绍了APP顶部导航栏AppBar,今天来介绍下Flutter实现APP底部导航栏。我们以仿写微信的底部导航栏来举例说明。要实现类似
- 在第一次启动项目的时候,由于使用了RabbitMQ的默认guest账号,怎么也登不进去,后来还是在Admin重新创建了一个其他的账号,然后开
- 前几天网上突然出现流言:某东发生数据泄露12G,最终某东在一篇声明中没有否认,还算是勉强承认了吧,这件事对于一般人有什么影响、应该怎么做已经
- 用的Idea,在写MyBatis时,测试发现有以下的报错信息Error parsing SQL Mapper Configuration.
- 如何使用union多表分页条件查询当前项目有一个全局搜索的功能,需要涉及到7-8张主表,由于当前项目使用的是Jpa,所以我决定使用原生sql
- 1、Java字符串在 Java 中字符串被作为 String 类型的对象处理。 String 类位于 java.lang 包中,默认情况下该
- if判断integer的问题昨天在使用mybatis的if判断integer时遇见一个小问题:<if test="isCho
- 在springboot中,默认继承好了一套完好的redis包,可以直接使用,但是如果使用中出了错不容易找到错误的原因,因此这里使用自己配置的