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);
 }
}

}

示例

下面的示例演示如何处理不太常见的情况:类继承自两个或多个接口,且每个接口都具有相同名称的事件。 在这种情况下,你必须为至少其中一个事件提供显式接口实现。 为事件编写显式接口实现时,还必须编写 addremove 事件访问器。 通常这些访问器由编译器提供,但在这种情况下编译器不提供它们。

通过提供自己的访问器,可以指定两个事件是由类中的同一个事件表示,还是由不同事件表示。 例如,如果根据接口规范应在不同时间引发事件,可以在类中将每个事件与单独实现关联。 在下面的示例中,订阅服务器确定它们通过将形状引用转换为 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#,接口,事件
0
投稿

猜你喜欢

  • java随机生成8位数授权码的实例

    2022-04-24 12:03:47
  • winfrom 在业务层实现事务控制的小例子

    2021-11-16 14:19:50
  • SpringBoot整合Apollo配置中心快速使用详解

    2022-12-25 17:00:34
  • Android自定义控件实现滑动开关效果

    2022-10-25 00:45:39
  • 浅谈SpringBoot资源初始化加载的几种方式

    2022-03-09 08:14:34
  • Java实战之实现一个好用的MybatisPlus代码生成器

    2023-06-18 02:16:10
  • java实现两个对象之间传值及简单的封装

    2022-03-11 13:53:18
  • IDEA中Mybatis的MGB使用逆向工程配置的详细教程

    2022-01-04 17:19:50
  • 浅谈java中的重载和重写的区别

    2023-03-31 04:45:57
  • C#中Timer使用及解决重入问题

    2022-02-21 00:44:52
  • springboot实现基于aop的切面日志

    2022-09-09 11:53:11
  • 带你了解C++的数组与函数

    2023-12-10 20:44:18
  • 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
  • 深入java垃圾回收的详解

    2021-11-19 10:33:06
  • Android中FoldingLayout折叠布局的用法及实战全攻略

    2021-05-23 19:29:17
  • Unity实现弹球打砖块游戏

    2021-09-24 16:13:08
  • Java算法实战之排一亿个随机数

    2022-11-22 02:47:26
  • asp之家 软件编程 m.aspxhome.com