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

}

示例

下面的示例演示如何处理不太常见的情况:类继承自两个或多个接口,且每个接口都具有相同名称的事件。 在这种情况下,你必须为至少其中一个事件提供显式接口实现。 为事件编写显式接口实现时,还必须编写 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.
*/

以上就是c#如何实现接口事件的详细内容,更多关于c# 实现接口事件的资料请关注我们其它相关文章!

(0)

相关推荐

  • C#Button窗体常用属性及事件详解

    1.常用属性 Name:名称: BackColor:设置控件背景颜色: Enabled:是否可用: FlayStyle:控件样式: Image:设置控件图像: ImageAlign:图像对齐方式: ImageList:图像ImageList索引值: Location:坐标: Size:大小: Tabindex:控件顺序索引: Text:文本: TextAlign:文本对齐方式: Visible:控件是否可见: 2.控件事件: Click:单击事件: 知识点扩充: 在真实的C#开发场景中,我们对于

  • 简单聊聊c# 事件

    引言: 前面几个专题对委托进行了详细的介绍的,然后我们在编写代码过程中经常会听到"事件"这个概念的,尤其是写UI的时候,当我们点击一个按钮后VS就会自动帮我们生成一些后台的代码,然后我们就只需要在Click方法里面写代码就可以,所以可能有些刚接触C#的朋友就觉得这样很理所当然的,也没有去思考这是为什么的,为什么点击下事件就会触发我们在Click方法里面写的代码呢?事件到底扮演个什么样的角色呢?为了解除大家的这些疑惑,下面就详细介绍了事件,让一些初学者深入理解C#中的事件的概念. 一.为

  • 详解C#之事件

    事件:定义了事件成员的类允许通知其他其他对象发生了特定的事情.具体的说,定义了事件成员的类能提供以下功能 1.方法能登记它对事件的关注 2.方法能注销它对事件的关注 3.事件发生时,登记了的方法将收到通知 类型之所以能提供事件通知功能,是因为类型维护了一个已登记方法的列表.事件发生后,类型将通知列表中所有已登记的方法. 事件是以委托为基础.委托是调用回调方法的一种类型安全的方式.对象凭借回调方法接收他们订阅的通知. 假如有一下场景:要设计一个电子邮件程序.当有新的邮件的到达时,用户希望做些一别的

  • .NET/C#如何使用反射注册事件详解

    前言 通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的名称.限定符和参数等.有了反射,即可对每一个类型了如指掌.如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道.那么如何注册事件呢? 本文将介绍如何使用反射注册事件.下面话不多说了,来一起看看看详细的介绍吧 不使用反射 例如,我们希望反射的类型是这样的: public class Walterlv { public e

  • C#事件实例详解

    C#事件实例详解 C#和JAVA有许多相似的地方,设计思想差不多,语法及其相像,均传承自面向对象设计思想,灵感来自C++并取其精华去其"糟粕(二字持保留意见)",中间语言.解释执行.一次编译.到处执行,出身豪门算得上是表兄弟关系,各自拥有庞大的拥趸,两种语言在发展的道路上你追我赶相互借鉴相互学习相互渗透,至于谁的IDE更强大对于一个用了二十年vim编辑器的人来说实在无从评判,强大到让人内牛满面~ C#语言中关于事件(event)结合代理(delegate)实现对象状态变更时的通知机制,

  • c#在程序中定义和使用自定义事件方法总结

    C#在程序中定义和使用自定义事件可以分为以下几个步骤: 步骤1:在类中定义事件 using System; public class TestClass { //.... public event EventHandler TestEvent } 步骤2:定义事件参数 注意:事件参数类TestEventArgs继承自System.EventArgs using System; public class TestEventArgs : EventArgs { public TestEventArg

  • C# 标准事件流实例代码

    服装价格变动,触发淘宝发布活动和消费者购买衣服事件流 public class EventStandard { public class Clothes { /// <summary> /// 服装编码 /// </summary> public string Id { get; set; } /// <summary> /// 服装名称 /// </summary> public string Name { get; set; } /// <summ

  • C#创建自定义控件及添加自定义属性和事件使用实例详解

    前言 C#本身提供了很强大的控件库,但是很多控件库的功能只是一些基本的功能,就比如最简单的按钮,C#提供了最基础的按钮使用方法,但是如果要增加一些功能,比如按钮按下要一个图片,弹起要另一个图片这样的工作.当然,我们可以对相关按钮在点击函数中进行更改其背景图片,但是这对于大量的按钮调用来说十分不方便,代码重用率相当的高,会导致使用上的卡顿,在这种情况下,我们可以将这个功能封装起来,这样每次调用起来就很方便,也节省了代码的重用率. 那么如何将上述的那么一个简单的功能封装起来呢,我们首先考虑到的便是按

  • C#事件管理器如何清空所有监听详解

    C#事件使用+= -=使用起来是很方便的,但是却不能整体清空所有事件.比如一个常见的操作,打开界面注册监听事件,关闭界面需要把所有的事件清空了,这要在写一堆-=操作,如果漏清空的话肯定会造成隐患,如果在lua里这个很容易,但是C#却不行.所以我想了个办法,对Action和Func进行一次包装,就可以解决这个问题了. 这里我只封装了两个参数,大家可以继续拓展新的参数,我在项目里一共拓展了5个参数,完全够用了. using System; using System.Collections.Gener

  • C#事件(event)使用方法详解

    事件(event),这个词儿对于初学者来说,往往总是显得有些神秘,不易弄懂.而这些东西却往往又是编程中常用且非常重要的东西.大家都知道windows消息处理机制的重要,其实C#事件就是基于windows消息处理机制的,只是封装的更好,让开发者无须知道底层的消息处理机制,就可以开发出强大的基于事件的应用程序来. 先来看看事件编程有哪些好处. 在以往我们编写这类程序中,往往采用等待机制,为了等待某件事情的发生,需要不断地检测某些判断变量,而引入事件编程后,大大简化了这种过程: - 使用事件,可以很方

随机推荐