委托

在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#]简单的理解委托和事件的更多相关文章

  1. 【详细】【转】C#中理解委托和事件 事件的本质其实就是委托 RabbitMQ英汉互翼(一),RabbitMQ, RabbitMQ教程, RabbitMQ入门

    [详细][转]C#中理解委托和事件   文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托 ...

  2. C#知识体系(二)用案例来理解委托与事件

    上一篇博客讲到了LinQ和lambda的常用方法 还有很多我们未知但c#设计团队已经为我们封装好的类和方法.随着我们不断的熟悉C#语言,渐渐的就会接触到其他的知识点,委托.事件.反射.线程.同步,异步 ...

  3. C#学习之初步理解委托、事件、匿名方法和Lambda

    最经在学习LinqtoSql,然后扯到Lambda表达式,然后扯到匿名方法,然后扯到委托,最后扯到事件处理...后来发现对委托这个概念和事件处理这个过程理解得不是很清晰,遂得一下学习笔记.那里说得不对 ...

  4. C#委托的定义 以及使用方式详解,更简单的理解委托。

    委托的声明及定义: 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得 ...

  5. C#基础篇 - 理解委托和事件

    1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针.简单理解,委托是一种可以把函数当做参数传递的类型.很多情况下,某 ...

  6. 【详细】【转】C#中理解委托和事件

    文章是很基础,但很实用,看了这篇文章,让我一下回到了2016年刚刚学委托的时候,故转之! 1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具 ...

  7. 通俗理解C#委托和事件

    引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...

  8. C# 委托和事件(一):最简单的委托和事件

    C#的事件基于委托,所以先说委托. 一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手.所以我需要一个实际的场景. 明天刚好考试(商务英语),考试上有两个角色(class):老师( ...

  9. C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介

    委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...

  10. C#编程之委托与事件四(一)【转】

    C#编程之委托与事件(一)     本文试图在.net Framework环境下,使用C#语言来描述委托.事件的概貌.希望本文能有助于大家理解委托.事件的概念,理解委托.事件的用途,理解它的C#实现方 ...

随机推荐

  1. Linux基础_3_文件/文件夹权限管理

    注:权限遮罩码: 控制用户创建文件和文件夹的默认安全设置,文件默认权限为666-umask的值,文件夹默认权限为777-umask的值. root默认0022,普通用户默认0002. 文件的默认权限不 ...

  2. 一天十道Java面试题----第一天(面向对象-------》ArrayList和LinkedList)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 1.面向对象 2.JDK.JRE.JVM区别和联系 3.==和equals 4.final 5.String .Strin ...

  3. 分享个好东西两行前端代码搞定bilibili链接转视频!

    只需要在您的要解析B站视频的页面的</body>前面加上下面两行代码即可,脚本会在客户端浏览器里解析container所匹配到的容器里的B站超链接 (如果不是外围有a标签的超链接只是纯粹的 ...

  4. SQL Server-表结构的操作

    1.修改表的字段的数据类型 alter table [File_Info] alter column Upload_Request_ID nvarchar(14) not null 2.添加表的字段并 ...

  5. Hexo多台电脑同步

    如果换了电脑该如何同步Hexo的源文件?把hexo文件从一个电脑cope到另外一个电脑吗?答案肯定不是这样的,因为这里面有好多依赖包,好几万个文件呢,这样显然不合理. 本文提供一种多台电脑同步源文件的 ...

  6. windows中 mysql 免安装版安装

    基本安装 绝对路径中避免出现中文,推荐首选英文为命名条件! 以管理员身份打开命令行,并转到mysql的bin目录下 安装mysql服务 mysqld --install 若出现以下错误,需将缺失的文件 ...

  7. Java安全之Mojarra JSF反序列化

    Java安全之Mojarra JSF反序列化 About JSF JavaServer Faces,新一代的Java Web应用技术标准,吸收了很多Java Servlet以及其他的Web应用框架的特 ...

  8. django 多 APP urls的实现

    项目下urls.py 引入admin from django.contrib import admin 引入path,include from django.urls import path,incl ...

  9. Solon v1.11.0 发布,Hello Java

    一个更现代感的 Java 应用开发框架:更快.更小.更自由.没有 Spring,没有 Servlet,没有 JavaEE:独立的轻量生态.主框架仅 0.1 MB. @Controller public ...

  10. easyui textbox setvalue 和 settext前后之别

    今天在这里转了好久,浪费了不少时间.话不多说直接上干货: 1.text与value设置不同的值一定要先赋值 value后赋值text, 否则全为value值 2.若只setValue,则getValu ...