C#2.0 委托

时间:2021-08-02 13:41:09

委托

委托是一个非常不错的设计,允许我们把方法做为参数传递,实现了开放閉放原则。在方法中我们只要有一个委托占位,调用者就可以传入符合签名的方法来做不同的操作,这也面向对象开发中多态的魅力。

但是在C#1.0的时候,委托写起来实际上是非常复杂的,首先我们要声明一个委托,然后再写一个符合委托签名的方法。再创建委托实例。然后才是调用,比如下面一个简单的例子,我要在winform程序中用户按了按键后我需要彈出一个消息

C#2.0 委托

因为委托的声明已经内置了,也就是KeyPressEventHandler所以我不用去写。简单一看似乎挺简洁,但是在winForm程序中会有着大量的事件,有些事件可能处理的方式非常简单,但是我们需要去相应的写一个方法。这也是比较头疼的问题。下面我们来看如何优化这个代码

方法组

在这面我们创建了一个委托实例,在C#1.0中,要同时指定委托类型和方法(操作)也就是如下图

C#2.0 委托

而在C#2.0中支持从方法组到一个兼容委托的隐式转换,也就是如果方法签名和委托声明完全相同,那么就不必再去new一个委托。这时代码就变成了

C#2.0 委托

但是有些方法并不是可以进行隐式转换的,如果方法需要一个Delegate类型的参数,那么我们的方法就不适用了,比如Invoke方法。这些我们就要显示转换

C#2.0 委托

协变与逆变

很多人都以为这是在4.0中才支持的,因为那时有了泛型的可变性。不过这个委托的可变性完全不同。

在winform中给我们内置很多的委托类型,比如上面用到的KeyPressEventHandler,还有MouseEventHandler,他们实际上区别不大,只是参数类型不同。第一个参数类型是KeyPressEventArgs,第二个是MouseEventArgs。

不同的事件对应不同的处理,这是没有问题的。但是我们可能会有不同的事件同样的处理这种需求。在C#1.0中很遺憾是没有办法的。而在C#2.0中我们可以使用逆变来解决这个问题

KeyPressEventArgs与MouseEventArgs都派生与EventArgs类型。实际上EventArgs的派生类有多达数百个。

我们只需要有一个具有EventAgrs类型的方法,就可以这么去做

C#2.0 委托

一个返回类型为基类的委托,我们想要用子类去实例化这个委托,这在之前是不可能的。而在C#2.0中,这已经没有任何问题

C#2.0 委托

匿名方法

在C#2.0中設計者也意识到了创建一个委托的步骤过于繁瑣,我们要有一个完整的方法,然后再创建委托实例进行调用,在C#2.0中则出现了匿名方法来帮助我们简化这一流程(3.0中的拉姆达则更加的方便)

下面就是一个简单的匿名方法创建委托实例的例子,拿到一个字符串然后去除两边空格打印出来

C#2.0 委托

虽然我们创建的是一个委托方法,但是编译成IL后每个匿名方法都会创建一个方法,会在匿名方法所在的类生成一个方法不过方法名则是乱七八糟的,不过也不是给程序员去看的。

闭包

使用方法就会使用到变量,对于匿名方法来说,分为外部变量与局部变量。很容易理解,外部变量就是匿名方法外声明的变量,而局部变量就是匿名方法内声明的变量。

如果匿名方法没有使用任何外部变量,那么则相安无事。如果使用了外部变量,那么它就是被捕获的外部变量。在匿名方法内对该变量的操作是有效的!

C#2.0 委托

为什么要说闭包,是因为匿名方法会在特成的情况下延长变量的生命周期,为什么这么说呢,大家都知道委托是方法的类型,可以把方法作为委托进行返回,如果一个方法里有一个委托实例,使用的是匿名方法并且捕获了外部变量,然后把这个委托实例进行返回。这时就形成了一个闭包

C#2.0 委托

这时如果去看IL会发现创建了一个新的类去容纳i变量,这也是为什么方法结束后i变量仍然存在的原因,还有一点需要注意的,外部变量只有一个,如果多个匿名方法捕获了它,那么这些匿名方法使用的都是一个变量,局部变量则没有这个问题

循环中创建的变量,每个委托捕获到的都是不同的变量

我们需要牢記的是

  • 補获的是变量,百不是创建委托初值时它的值
  • 捕获的变量生命周期被延长,至少和捕捉它的委托一样长
  • 多个委托可以捕获同一个变量
  • 必要时创建额外的类型来保存捕获变量

C#2.0 委托的更多相关文章

  1. 委托,匿名函数和lambda表达式

    很早之前就接触到了委托,但是一直对他用的不是太多,主要是本人是菜鸟,能写的比较高级的代码确实不多,但是最近在看MSDN微软的类库的时候,发现了微软的类库好多都用到了委托,于是决定好好的研究研究,加深一 ...

  2. C#—委托分析

    1.简单委托示例 using System; using System.Collections.Generic; using System.Linq; using System.Text; names ...

  3. C# 语言规范_版本5.0 (第1章 介绍)

    1. 介绍 C#(读作“See Sharp”)是一种简洁.现代.面向对象且类型安全的编程语言.C# 起源于 C 语言家族,因此,对于 C.C++ 和 Java 程序员,可以很快熟悉这种新的语言.C# ...

  4. C#6.0语言规范(一) 介绍

    C#(发音为“See Sharp”)是一种简单,现代,面向对象,类型安全的编程语言.C#源于C语言系列,对C,C ++和Java程序员来说很熟悉.EC#International将EC#标准化为ECM ...

  5. C# Language Specification 5.0 (翻译)第一章 引言

    C#(念作 See Sharp)是一种简单.现代.面向对象并且类型安全的编程语言.C# 源于 C 语言家族,因此 C.C++ 和 Java 工程师们能迅速上手.ECMA 国际[1](ECMA Inte ...

  6. C#3.0新特性:隐式类型、扩展方法、自动实现属性,对象/集合初始值设定、匿名类型、Lambda,Linq,表达式树、可选参数与命名参数

    一.隐式类型var 从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var.隐式类型可以替代任何类型,编译器自动推断类型. 1.var类型的局部变量必须赋予初始值,包括匿名 ...

  7. C#指南,重温基础,展望远方!(11)C#委托

    委托类型表示对具有特定参数列表和返回类型的方法的引用. 通过委托,可以将方法视为可分配给变量并可作为参数传递的实体. 委托类似于其他一些语言中的函数指针概念,但与函数指针不同的是,委托不仅面向对象,还 ...

  8. C#中委托的发展与匿名函数

    匿名函数(C# 编程指南) 匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用. 可以使用匿名函数来初始化命名委托,或传递命名委托(而不是命名委托类型)作为方法参数. 共有两种匿名函数 ...

  9. jquery2.0.3 全部源码

    /*! * Includes Sizzle.js 选择器,独立的库 * http://sizzlejs.com/ */ (function( window, undefined ) { //&quot ...

随机推荐

  1. ImageView学习

    package liu.roundimagedemo.view; import android.content.Context; import android.graphics.Bitmap; imp ...

  2. C#反序化json字符串,不用区分大小写

    最近在做第三方对接的项目,接口返回的数据是json格式,并且每个字段都是小写的,而我们程序类中的属性是要求大写的:刚开始想到的是用JavaScriptSerializer,但是这个并不满足需求 就换了 ...

  3. WCF学习笔记之消息交换模式

    在WCF通信中,有三种消息交换模式,OneWay(单向模式), Request/Reponse(请求回复模式), Duplex(双工通信模式)这三种通信方式.下面对这三种消息交换模式进行讲解. 1. ...

  4. Aspose.word总结

    1.创建word模版,使用MergeFeild绑定数据     新建一个Word文档,命名为Template.doc     注意:这里并不是输入"<”和“>”就可以了,而是必须 ...

  5. 【PythonChallenge】Level 4

    如题,是一个链表,N多数据,其中还有其它操作,比较麻烦,也是刚学python网络编程.对于Perl的RE很熟悉,还没有学python的,还是啃手册吧.其中在读出16044时,并没有找到匹配项,如下图所 ...

  6. &lpar;简单&rpar; POJ 3074 Sudoku&comma; DLX&plus;精确覆盖。

    Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgr ...

  7. Formdata 图片上传 Ajax

    /*图片上传*/ $("点击对象").bind("click", function(e){ $('#form-upload').remove(); $('bod ...

  8. EBS系统克隆

     术语 克隆是对已有的Oracle应用系统创建一份拷贝的过程.克隆一个Oracle应用系统有几种不同的情况,包括: l   标准克隆 – 复制一个已有的Oracle应用系统生成一份拷贝,例如对生产 ...

  9. 记华硕小主机装xp并给nokia e7-00 刷机

    前言 事情是这样的,年前给早先收的小e买了触摸外屏.这会儿有空就给它换上了屏幕,然后尝试装app的时候,发现证书有问题. 根据以往使用n73的经验,然后就百度怎么破解证书. 然后我发现,这些东西网上资 ...

  10. 一起学python-语法

    1.print 输出 2.定义变量:就是给变量赋一个值 name ='haha' print (name) 3.注释代码:# 注释快捷键:Ctrl +/ 4.单双引号: 如果字符串里面有单引号,外面就 ...