程序地带

.NET 准则的事件(C# 编程指南)


 


下面的过程演示了如何将遵循标准 .NET 模式的事件添加到类和结构中。The following procedure demonstrates how to add events that follow the standard .NET pattern to your classes and structs. .NET 类库中的所有事件均基于 EventHandler 委托,定义如下:All events in the .NET class library are based on the EventHandler delegate, which is defined as follows:


C#
publicdelegate void EventHandler(object sender, EventArgs e);

备注


.NET Framework 2.0 引入了泛型版本的委托 EventHandler<TEventArgs>。.NET Framework 2.0 introduces a generic version of this delegate, EventHandler<TEventArgs>. 下例演示了如何使用这两个版本。The following examples show how to use both versions.


尽管定义的类中的事件可基于任何有效委托类型,甚至是返回值的委托,但一般还是建议使用 EventHandler 使事件基于 .NET 模式,如下例中所示。Although events in classes that you define can be based on any valid delegate type, even delegates that return a value, it is generally recommended that you base your events on the .NET pattern by using EventHandler, as shown in the following example.


名称 EventHandler 可能导致一些混淆,因为它不会实际处理事件。The name EventHandler can lead to a bit of confusion as it doesn"t actually handle the event. EventHandler 和泛型 EventHandler<TEventArgs> 均为委托类型。The EventHandler, and generic EventHandler<TEventArgs> are delegate types. 其签名与委托定义匹配的方法或 Lambda 表达式是事件处理程序,并将在引发事件时调用。A method or lambda expression whose signature matches the delegate definition is the event handler and will be invoked when the event is raised.


发布基于 EventHandler 模式的事件Publish events based on the EventHandler pattern

(如果无需随事件一起发送自定义数据,请跳过此步骤转到步骤 3a。)将自定义数据的类声明为对发布服务器和订阅者类均可见的范围。(Skip this step and go to Step 3a if you do not have to send custom data with your event.) Declare the class for your custom data at a scope that is visible to both your publisher and subscriber classes. 然后添加所需成员以保留自定义事件数据。Then add the required members to hold your custom event data. 在此示例中,将返回一个简单的字符串。In this example, a simple string is returned.


C#
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
}

(如果使用的是泛型版本 EventHandler<TEventArgs>,请跳过此步骤。)声明发布类中的委托。(Skip this step if you are using the generic version of EventHandler<TEventArgs>.) Declare a delegate in your publishing class. 为其指定以 EventHandler 结尾的名称。Give it a name that ends with EventHandler. 第二个参数指定自定义 EventArgs 类型。The second parameter specifies your custom EventArgs type.


C#
public delegate void CustomEventHandler(object sender, CustomEventArgs args);

使用下列步骤之一来声明发布类中的事件。Declare the event in your publishing class by using one of the following steps.


如果没有任何自定义 EventArgs 类,事件类型将为非泛型 EventHandler 委托。If you have no custom EventArgs class, your Event type will be the non-generic EventHandler delegate. 你无需声明该委托,因为它已在创建 C# 项目时包括的 System 命名空间中声明。You do not have to declare the delegate because it is already declared in the System namespace that is included when you create your C# project. 将以下代码添加到发布服务器类。Add the following code to your publisher class.


C#
public event EventHandler RaiseCustomEvent;

如果使用非泛型版本 EventHandler 并且具有派生自 EventArgs 的自定义类,请声明发布类中的事件,并将步骤 2 中的委托用作类型。If you are using the non-generic version of EventHandler and you have a custom class derived from EventArgs, declare your event inside your publishing class and use your delegate from step 2 as the type.


C#
public event CustomEventHandler RaiseCustomEvent;

如果使用泛型版本,则无需自定义委托。If you are using the generic version, you do not need a custom delegate. 而是在发布类中,将事件类型指定为 EventHandler<CustomEventArgs>,替换尖括号中自定义类的名称。Instead, in your publishing class, you specify your event type as EventHandler<CustomEventArgs>, substituting the name of your own class between the angle brackets.


C#
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
示例Example

下例通过使用自定义 EventArgs 类和 EventHandler<TEventArgs> 作为事件类型来演示之前的步骤。The following example demonstrates the previous steps by using a custom EventArgs class and EventHandler<TEventArgs> as the event type.


C#
using System;
namespace DotNetEvents
{
// Define a class to hold custom event info
public class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
Message = message;
}
public string Message { get; set; }
}
// Class that publishes an event
class Publisher
{
// Declare the event using EventHandler<T>
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
public void DoSomething()
{
// Write some code that does something useful here
// then raise the event. You can also raise an event
// before you execute a block of code.
OnRaiseCustomEvent(new CustomEventArgs("Event triggered"));
}
// Wrap event invocations inside a protected virtual method
// to allow derived classes to override the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
// Make a temporary copy of the event to avoid possibility of
// a race condition if the last subscriber unsubscribes
// immediately after the null check and before the event is raised.
EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;
// Event will be null if there are no subscribers
if (raiseEvent != null)
{
// Format the string to send inside the CustomEventArgs parameter
e.Message += $" at {DateTime.Now}";
// Call to raise the event.
raiseEvent(this, e);
}
}
}
//Class that subscribes to an event
class Subscriber
{
private readonly string _id;
public Subscriber(string id, Publisher pub)
{
_id = id;
// Subscribe to the event
pub.RaiseCustomEvent += HandleCustomEvent;
}
// Define what actions to take when the event is raised.
void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine($"{_id} received this message: {e.Message}");
}
}
class Program
{
static void Main()
{
var pub = new Publisher();
var sub1 = new Subscriber("sub1", pub);
var sub2 = new Subscriber("sub2", pub);
// Call the method that raises the event.
pub.DoSomething();
// Keep the console window open
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
}
}
}
 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/fu609277362/p/14210841.html

随机推荐

在稀疏域中发现用户社区

发表在2020年SIGIR《DetectingUserCommunityinSparseDomainviaCross-GraphPairwiseLearning》论文阅读笔记背景:网络空...

Xidian小韩同学 阅读(133)

分布式项目软件使用(配置与操作)

Nginx反向代理和负载均衡1.1为什么需要反向代理需求:当完成文件上传时,业务返回页面的是虚拟地址路径url地址:http://image.jt.com/2020/09/30/a.jpg真实图片地址...

Fish Swimming 阅读(900)

被动语态和非谓语区别_非谓语动词:分词

教育丨阅读丨生活丨成长近期热点中考听力1800词仁爱护眼笔记人教音频语法仁爱视频讲解初中语法精选外研初中英语细说新概念分词就两种:现在分词和过去分词,分别都可以作定语也可以...

空明流转 阅读(879)

oracle的分页查询

以前工作接触到的数据库都是mysql,分页用limit,最近需要写一个oracle的分页查询,在网上找到了方法,记录一下:sele...

A cold winter 阅读(628)

ensp 查看命令(display)

ensp查看命令(display)displaythis查看当前配置过的命令displaycurrent-configuration查看所有配置(简写disc...

余帆的小黑屋 阅读(266)

jdk版本共存

切换jdk1.7的步骤2.安装jdk1.7应该不用多说,就是将jdk和jre分别装到不同的文件夹下,这个步骤就跳过咯。3.接下就是配置环境变量,首先先配置JA...

qq_46511838 阅读(497)

DOM查询

北京首都啊南京你是几线东京一边去西天取经你来当和尚吧先获取ul标签varul=document.getElementsByTagName("ul")[0]获取ul下所有的子元素...

a15_41 阅读(1000)