C#语言进阶(二)—事件 第三篇(事件访问器)

2024-06-01 12:36

本文主要是介绍C#语言进阶(二)—事件 第三篇(事件访问器),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

总目录
C# 语法总目录

系列链接
C#语言进阶(二)    事件 第一篇(发布订阅模式)
C#语言进阶(二)    事件 第二篇(.net标准事件模型)
C#语言进阶(二)    事件 第二篇(事件访问器)

事件 第三篇目录

    • 事件 第三篇
      • 3. 事件访问器

事件 第三篇

3. 事件访问器

  默认情况下,编译器会默认实现事件的访问器,如果显示的去实现,那么编译器就不会自动取生成默认的访问器。

  从功能上,自己手动写访问器和编译器默认生成是一样的,但是编译器默认生成的使用了无锁的比较并交换算法,保证在更新委托时的线程安全性,在多线程情况下更安全些。

  一般情况不需要自己去显示写事件访问器,如果需要更多高级操作,那么就不得不用。

以下是一些可能需要用的情况 (当然也可以不用):

  • 当事件很多,订阅者却不多,这种情况下需要自定义访问器的add方法,在方法里使用字典来存储委托引用,这样比原来的开销小
  • 当广播类继承了多个事件接口,并且有多个接口的事件名称是相同的,那么需要把这些接口的事件显示的去创建访问器,用来区分它们用哪个访问器访问

含有相同事件的接口

public interface IMathScore
{event EventHandler<ScoreChangedCusEventArgs> ScoreChanged;
}
public interface IEnglishScore
{event EventHandler<ScoreChangedCusEventArgs> ScoreChanged;
}

标准事件参数类

public class ScoreChangedCusEventArgs : EventArgs
{public static readonly new ScoreChangedCusEventArgs? Empty;//通常标准事件模型传递的参数设置为只读类型public readonly decimal oldScore;public readonly decimal newScore;public ScoreChangedCusEventArgs(decimal oldScore, decimal newScore){this.oldScore = oldScore;this.newScore = newScore;}
}

发布者类

//发布者
public class BroadCasterCusStandar:IMathScore,IEnglishScore
{private string? name;private decimal englishScore;private decimal mathScore;event EventHandler<ScoreChangedCusEventArgs> MathEvent;event EventHandler<ScoreChangedCusEventArgs> EnglishEvent;object objectLock = new Object();event EventHandler<ScoreChangedCusEventArgs>? IMathScore.ScoreChanged{add {lock (objectLock){MathEvent += value;}}remove {lock (objectLock){MathEvent -= value;}}}event EventHandler<ScoreChangedCusEventArgs>? IEnglishScore.ScoreChanged{add{lock (objectLock){EnglishEvent += value;}}remove{lock (objectLock){EnglishEvent -= value;}}}protected virtual void OnMathScoreChanged(ScoreChangedCusEventArgs? e){MathEvent?.Invoke(this, e);}protected virtual void OnEnglishScoreChanged(ScoreChangedCusEventArgs? e){EnglishEvent?.Invoke(this, e);}public BroadCasterCusStandar(string name){this.name = name;}public decimal MathScore{get { return mathScore; }set{if (mathScore == value) return;decimal oldMathScore = mathScore;mathScore = value;OnMathScoreChanged(new ScoreChangedCusEventArgs(oldMathScore, mathScore));//如果不需要传值,那么可以用下面代替//OnMathScoreChanged(ScoreChangedCusEventArgs.Empty);}}public decimal EnglishScore{get { return englishScore; }set{if (englishScore == value) return;decimal oldEnglishScore = englishScore;englishScore = value;OnEnglishScoreChanged(new ScoreChangedCusEventArgs(oldEnglishScore, englishScore));//如果不需要传值,那么可以用下面代替//OnEnglishScoreChanged(ScoreChangedCusEventArgs.Empty);}}
}

订阅者类

//订阅者
internal class SubscriberCus1Standar
{private readonly string _id;public SubscriberCus1Standar(string id, BroadCasterCusStandar broad){_id = id;IEnglishScore englishBroad = (IEnglishScore)broad;//订阅信息englishBroad.ScoreChanged += ScoreChanged;}//处理广播信息void ScoreChanged(object? obj, ScoreChangedCusEventArgs e){if (e == ScoreChangedCusEventArgs.Empty){return;}Console.WriteLine("this id is: " + _id + ",  oldscore is " + e.oldScore + "  ,new Score is: " + e.newScore + "  ,time is: " + DateTime.Now);}
}

订阅者类

internal class SubscriberCus2Standar
{private readonly string _id;public SubscriberCus2Standar(string id, BroadCasterCusStandar broad){_id = id;IMathScore englishBroad = (IMathScore)broad;//订阅信息englishBroad.ScoreChanged += ScoreChanged;}//处理广播信息void ScoreChanged(object? obj, ScoreChangedCusEventArgs e){if (e == ScoreChangedCusEventArgs.Empty){return;}Console.WriteLine("this id is: " + _id + ",  oldscore is " + e.oldScore + "  ,new Score is: " + e.newScore + "  ,time is: " + DateTime.Now);}
}

输出

//输出
this id is: 02,  oldscore is 0  ,new Score is: 15  ,time is: 2000/1/1 17:34:35
this id is: 01,  oldscore is 0  ,new Score is: 20  ,time is: 2000/1/1 17:34:35 

总目录
C# 语法总目录

系列链接
C#语言进阶(二)    事件 第一篇(发布订阅模式)
C#语言进阶(二)    事件 第二篇(.net标准事件模型)
C#语言进阶(二)    事件 第二篇(事件访问器)

这篇关于C#语言进阶(二)—事件 第三篇(事件访问器)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1021025

相关文章

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

C# Where 泛型约束的实现

《C#Where泛型约束的实现》本文主要介绍了C#Where泛型约束的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用的对象约束分类where T : structwhere T : classwhere T : ne

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代