[C#]简单的理解委托和事件
委托
在C++中可以利用“函数指针”将对方法的引用作为实参传递给另一个方法,而C#中可以利用委托提供相同的功能。
委托-内部机制
但是委托实际上是一个特殊的类。委托必须直接或间接的派生自System.Delegate。实际的委托类型总是派生自System.MulticastDelegate(创建委托的时候,编译器自动继承的是MulticastDelegate而不是Delegate),后者又从Delegate派生。
委托内部包含了几个重要的属性:第一个就是System.Reflection.MethodInfo类型的,它描述了特定方法的签名,包括方法名称、参数和返回类型。除了MethodInfo,委托还需要一个对象实例,其中包含了要调用的方法,这是第二个属性Target的作用。(如果是静态方法,则Target对应类型自身)。
Func和Action
为了减少自定义委托类型的必要,.NET 3.5包含了一组通用的委托,其中大多数都是泛型。System.Func系列委托代表有返回值的方法,而System.Action表示返回void的方法。
Public delegate void Action();
Public delegate void Action<in T>(T arg)
Public delegate void Action<in T1,in T2>(in T1 arg1,in T2 arg2)
Public delegate void Action<in T1,in T2,in T3>(in T1 arg1,in T2 arg2,in T3 arg3)
…….
Public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16>(T1 arg1,T2 arg2,T3 arg3,T4 arg4,T5 arg5,T6 arg6,T7 arg7,T8 arg8,T9 arg9,T10 arg10, T11 arg11,T12 arg12, T13 arg13, T14 arg14,T15 arg15, T16 arg16)
Public delegate Tresult Func<out TResult>();
Public delegate Tresult Func<in T,out TResult>(T arg);
Public delegate Tresult Func<in T1,in T2,out TResult>(T1 arg1,T2 arg2);
……
Public delegate Tresult Func<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,out TResult>(T1 arg1,T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6,T7 arg7,T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15,T16 arg16)
事件
说到事件,得知道委托的几个缺陷:
1、在使用+=赋值操作符时使用了=,会导致一个全新的委托链代替了前面链,这是一个十分容易犯的错误,所以event提供了额外的封装,避免不小心取消了其他订阅者。
2、可以在委托包容类的外部调用委托,这是由于委托的封装不充分。
3、普通委托还有一个不利之处在于,很容易忘记在调用委托之前检查null值(在C#6中使用 ?. null条件操作符),这会引发一个异常。
而事件就可以很简单的理解了,就是对委托的进一步封装,解决了委托存在的一些缺陷。
事件-内部机制
事件限制外部类只能通过+=操作符向发布者添加订阅方法,并用-=操作符取消订阅,除此之外什么都不能做。此外,还禁止除包容类之外的任何其他类调用事件。为了达到上述目的,C#编译器会获取带有event修饰符的public委托变量,并将委托声明为private。此外,它还会添加两个方法和两个特殊的事件块,这里就不展开了。
[C#]简单的理解委托和事件的更多相关文章
- 【详细】【转】C#中理解委托和事件 事件的本质其实就是委托 RabbitMQ英汉互翼(一),RabbitMQ, RabbitMQ教程, RabbitMQ入门
[详细][转]C#中理解委托和事件 文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托 ...
- C#知识体系(二)用案例来理解委托与事件
上一篇博客讲到了LinQ和lambda的常用方法 还有很多我们未知但c#设计团队已经为我们封装好的类和方法.随着我们不断的熟悉C#语言,渐渐的就会接触到其他的知识点,委托.事件.反射.线程.同步,异步 ...
- C#学习之初步理解委托、事件、匿名方法和Lambda
最经在学习LinqtoSql,然后扯到Lambda表达式,然后扯到匿名方法,然后扯到委托,最后扯到事件处理...后来发现对委托这个概念和事件处理这个过程理解得不是很清晰,遂得一下学习笔记.那里说得不对 ...
- C#委托的定义 以及使用方式详解,更简单的理解委托。
委托的声明及定义: 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得 ...
- C#基础篇 - 理解委托和事件
1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针.简单理解,委托是一种可以把函数当做参数传递的类型.很多情况下,某 ...
- 【详细】【转】C#中理解委托和事件
文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具 ...
- 通俗理解C#委托和事件
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...
- C# 委托和事件(一):最简单的委托和事件
C#的事件基于委托,所以先说委托. 一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手.所以我需要一个实际的场景. 明天刚好考试(商务英语),考试上有两个角色(class):老师( ...
- C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介
委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...
- C#编程之委托与事件四(一)【转】
C#编程之委托与事件(一) 本文试图在.net Framework环境下,使用C#语言来描述委托.事件的概貌.希望本文能有助于大家理解委托.事件的概念,理解委托.事件的用途,理解它的C#实现方 ...
随机推荐
- Linux系统管理_网络管理
常用网络指令 yum -y install net-tools #安装ifconfig工具 ifconfig #查看网络配置 ifup ens33 #启用网卡 ifdown ens33 #禁用网卡 s ...
- JSON parse error: Cannot deserialize value of type `java.lang.Integer` from Boolean value
问题原因所在:前端Vue传输的数据字段类型和后端实体类字段不一致. 我的实体类字段是int类型.前端传输的数据是布尔类型. 文章目录 1.后端方法 2.实体类字段 2.前端传输的数据 1.后端方法 @ ...
- 一天十道Java面试题----第三天(对线程安全的理解------>线程池中阻塞队列的作用)
这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 21.对线程安全的理解 22.Thread和Runnable的区别 23.说说你对守护线程的理解 24.ThreadLoc ...
- 知识图谱顶会论文(ACL-2022) CAKE:用于多视图KGC的可扩展常识感知框架
CAKE:用于多视图KGC的可扩展常识感知框架.pdf 论文地址:CAKE:Scalable Commonsense-Aware Framework For Multi-View Knowledge ...
- C# 7.0 添加和增强的功能【基础篇】
C# 7.0 版是与 Visual Studio 2017 一起发布. 虽然该版本继承和发展了C# 6.0,但不包含编译器即服务. 一.out 变量 以前我们使用out变量必须在使用前进行声明,C# ...
- javascript编程单线程之异步模式Asynchronous
异步模式Asynchronous 不会等待这个任务结束才开始执行下一个任务,开启之后立即执行下一个任务,后续逻辑一般会通过回调函数的方式定义,异步模式对js 非常重要,没有异步任务单线程的 js 语言 ...
- QML 怎么调用 C++ 中的内容?
以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://mp.weixin.qq.com/s/z_JlmNe6cYldNf11Oad_JQ 先说明一下测试环境 编 ...
- Python基础之模块:1、模块的导入和使用
目录 一.模块 1.简介 2.模块的表现形式 二.模块的分类 1.自定义模块 2.内置模块 3.第三方模块 三.导入模块的句式 学前须知: 1.import句式 2.from...import...句 ...
- 将vue+nodejs项目部署到服务器上(完整版)
1.后端使用express生成器 1.1.后台node项目部署 在node项目里安装cors依赖(跨域)npm install cors --save,在app.js文件中使用var cors = r ...
- Vue3 企业级优雅实战 - 组件库框架 - 1 搭建 pnpm monorepo
前两篇文章分享了基于 vite3 vue3 的组件库基础工程 vue3-component-library-archetype 和用于快速创建该工程的工具 yyg-cli,但在中大型的企业级项目中,通 ...