委托

最近自己在调试C#项目,发现经常可以看到委托和lambda表达式,各种花里胡哨的写法把我给整的云里雾里的,于是自己特意花了一点功夫来整理关于delegate的相关知识,方便自己日后查阅。

何为委托

委托是.NET中的寻址方法,和C++的函数指针很像;但是委托是类型安全的类,定义了返回类型和参数类型,也就是说委托一种用户自定义的类型,和普通的类一样;

委托的使用

声明委托

    delegate void IntMethodInvoker(int x);    //定义委托IntMethodInvoker, 参数是int,返回类型void

我们可以把委托当做是一件事情,就是给方法名字和返回类型指定一个别名

从上面的例子可以总结出声明委托的模板如下:

  • delegate + 返回类型 + 委托类型名 + 参数列表

委托的使用

实例化委托,并且需要对其进行初始化,这样可以类似地当做一个变量使用了,下面给出一个具体的例子来说明如何使用委托。

    using System;

    namespace DelegateSamples{

        delegate double DoubleOp(double x);    // 声明一个委托类型
class MathOperations
{
public static doube MultiplyByTwo(double value)
return value * 2; public static double Square(double value)
return value * value;
} class Program
{
static void Main()
{
// 声明一个委托数组,就像普通数组一样
DoubleOp[] operations = {MathOperations.MultiplyByTwo, MathOperations.Square}; for(int i = 0; i < operations.length; i++)
{
Console.WriteLine("using operations[{0}]:", i);
ProcessAndDisplayNumber(operations[i], 3.2);
Console.WriteLine();
}
} static void ProcessAndDisplayNumber(DoubleOp action, double value)
{
double res = action(value); // 调用action实际封装的方法
Console.WrireLine("Value is {0}, result of operation is {1}", value, res);
}
}

在调用委托的时候,最后判断委托是否为null,不然可能会引起异常

Action和Func委托

Action<T>委托表示引用一个void返回类型的方法,Action<T>有很多种变体,Action<in T>调用带一个参数的方法,没有泛型参数的Action类调用不带参数的方法;

Func<T>委托类似,表示引用带返回类型的方法,Func<T>也有很多变体,Func<Out TResult>表示调用带返回类型但没有参数的方法,Func<in T, out TRsult>调用一个带参数的方法,以此类推;

// 声明一个返回double类型,并且带一个double参数的委托
Func <double, double> operations = {MathOperations.MultiplyByTwo, MathOperations.Square}; // 注意这个方法和上面方法的不一样,利用了Func类
static void ProcessAndDisplayNumber(Func <double, double> action, double value)
{
double res = action(value); // 调用action实际封装的方法
Console.WrireLine("Value is {0}, result of operation is {1}", value, res);
}

多播委托

在之前的例子中,每个委托都只含有一个方法调用,也就是说调用多少次委托就是调用多少次方法。

但是,一个委托也可以包含多个方法,这种委托叫做多播委托,因此,这种委托必须返回void,不然返回的数据是不对的

    Action<double> operations = MathOperations.MultiplyByTwo;
operations += MathOperations.Square; //这里在给委托添加一个方法

对于多播委托的使用,调用方法链的顺序并没得到正式定义,这要求我们尽量避免依赖特定顺序调用方法的代码;

从上面的例子可以知道,多播委托是可以识别+,+=,-,-=这些符号的,下面给出具体的示意:

  • +=: 表示委托新增一个方法
  • -=: 表示委托减少一个方法

匿名方法

在上面的例子中,委托所调用的方法,都是我们自己预先写好的,但是委托也可以使用匿名方法,也就是将匿名方法用作委托的参数,这在实例化委托的会有一些不一样的,具体如下面例子所示:

    string name = "";

    // Func<string, string>委托接受一个string参数,返回一个string,注意匿名方法的实现,delegate开头
Func<string, string> anonDel = delegate(string param){
param += name;
param += "just for test";
return param;
};

使用匿名方法需要遵守的规则:

  1. 在匿名方法中不能使用跳转语句(goto、break、continue),匿名方法外部的语句也不能跳转到匿名方法内部;
  2. 在匿名方法中不能访问不完全的代码,也不能访问在匿名方法外部定义的ref、out参数;

在C#3.0之后,lambda表达式代替了匿名方法,写起来感觉更舒服;

Lambda表达式

lambda表达式主要是用来替代匿名方法的,因为显然委托知道他自己需要调用的是什么方法,不需要声明delegate关键字,在参数和方法体之间插入=>,表示“goes to",具体示例如下所示:

    string name = "";

    // Func<string, string>委托接受一个string参数,返回一个string,这里使用lambda表达式
Func<string, string> anonDel = param => {
param += name;
param += "just for test";
return param;
};
// 这样的lambda表达式是不是很优雅,就是调试程序的时候会有点烦

为了更好地使用lambda表达式,方便我们自己写代码写的花里花哨的,就对其多做一点介绍:

参数

  1. 如果只有一个参数,就只需要写出参数名字就行

     Func<string, string> oneParam = s => String.Format("change to Upper {0}", s.ToUpper());
  2. 使用多个参数,就把参数用写在()里

    Func<double, double, double> twoParams= (x, y) => x * y;    // 返回x*y

在使用多个参数的时候,我觉得还是在参数前面加上类型比较好,便于理解,例如(double x, double y) => x * y;

多行代码

  1. 只有一条语句,方法里面不需要{}和return,编译器会自动添加一个隐式的return

     Func<double, double, double> result = x, y => x * y;
  2. 含有多条语句,需要加上{}和return

    string lastname = "Alex";
    Func<string ,string> printName = name =>
    {
    name += lastname;
    return String.Format("Being Upper: {0}",name);
    }

c#学习笔记之委托的更多相关文章

  1. 《C# 语言学习笔记》——委托

    委托是一种可以把引用存储为函数的类型. 委托的声明非常类似于函数,但不带函数体,且要使用delegate关键字.委托的声明制定了一个返回类型和一个参数列表. 在定义了委托后,就可以声明该委托类型的变量 ...

  2. [读书笔记]C#学习笔记二: 委托和事件的用法及不同.

    前言:  C#委托是什么 c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针 ...

  3. [C#学习笔记]Func委托与Action委托

    学习一项新知识的时候,最好的方法就是去实践它. 前言 <CLR via C#>这本神书真的是太有意思了!好的我的前言就是这个. Fun 如果要用有输入参数,有返回值的委托,那么Func委托 ...

  4. js学习笔记-事件委托

    通过事件委托,你可以把事件处理器绑定到父元素上,避免了把事件处理器添加到多个子级元素上.从而优化性能. 事件代理用到了事件冒泡和目标元素.而任何一个元素的目标元素都是一开始的那个元素. 这里首先要注意 ...

  5. 【c# 学习笔记】委托链的使用

    委托链其实就是委托类型,只是委托链把多个委托链接在一起而已,也就是说,我们把链接了多个方法的委托称为委托链或多路广播委托.如下: public delegate void DelegateTest() ...

  6. 【c# 学习笔记】委托的使用

    //委托使用的演示 class Program { //1.使用delegate关键字来定义一个委托类型 public delegate void MyDelegate(int para1, int ...

  7. c#学习笔记03——委托和事件

    委托:一种引用类型,这种类型可以用来定义方法签名,从而使用委托实现将方法作为参数传递给其他方法.类似于C++中的函数之争,使用委托使程序员可以将方法引用封装在委托对象内. 定义和声明委托: deleg ...

  8. 委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式

    引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录 ...

  9. C#委托与事件学习笔记

    委托事件学习笔记 本文是学习委托和事件的笔记,水平有限,如有错漏之处,还望大神不吝赐教. 什么是委托?从字面意思来解释,就是把一个动作交给别人去执行.在实际开发中最常用的就是使一个方法可以当做一个参数 ...

随机推荐

  1. 【转】JavaScript 3D图表

    文章系本人原创,转载请保持完整性并注明出自<四火的唠叨> 在说3D图表以前,首先要明确两个概念,一个是数据的维度,一个是呈现数据载体的维度.对于数据的维度,一维的数据呈现,但是呈现的载体是 ...

  2. (2)MongoDB副本集自动故障转移原理

    前文我们搭建MongoDB三成员副本集,了解集群基本特性,今天我们围绕下图聊一聊背后的细节. 默认搭建的replica set均在主节点读写,辅助节点冗余部署,形成高可用和备份, 具备自动故障转移的能 ...

  3. 从源码角度了解SpringMVC的执行流程

    目录 从源码角度了解SpringMVC的执行流程 SpringMVC介绍 源码分析思路 源码解读 几个关键接口和类 前端控制器 DispatcherServlet 结语 从源码角度了解SpringMV ...

  4. 【C_Language】---一份程序看懂C程序printf()的几种常用用法

    闲来继续巩固我的学习之路,今天略微整理了一下,C程序中Printf()的一些常用用法,虽然自己以前好像会,但是不够系统,今天大致整理了一些,先贴上来看看,以后在看到其他,继续补充,希望能帮到一些像我一 ...

  5. Docker 学习 1 入门

    Docker 学习 1 入门 dockert 安装. Mac Ubuntu 查看docker 版本 docker version 拉取image. docker pull e.g docker pul ...

  6. .net core webapi搭建(2)跨域

    Core WebAPI中的跨域处理 在使用WebAPI项目的时候基本上都会用到跨域处理 Core WebAPI的项目中自带了跨域Cors的处理,不需要单独添加程序包 如图所示 修改 Configure ...

  7. [hdu2255] 奔小康赚大钱

    Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有 \(n\) 间房间,刚好有 \(n\) 家 ...

  8. 批量解决win10图标上有两个蓝色箭头的方法

    双击“此电脑”,点击“C盘”,可以看到一个”用户“文件夹,双击”用户“, 选择现在正在使用的用户名,双击用户名,找到该文件夹下的”桌面“或”Desktop“点击“属性”, 在“常规”选项卡中的属于项中 ...

  9. 基于Bootstrap和Knockout.js的ASP.NET MVC开发实战 关于 拦截器的 学习 部分

    先贴一段: 下面贴代码: 上面这段代码呢,有几个点迷糊.可以找找看

  10. GitHub 上这几个沙雕项目,够我玩几天

    在家里都憋坏了吧?每天睡了吃吃了睡,该找点事做做了,今天推荐几个好(沙)玩(雕)的开源项目,好在家打发时间. 91 吴先生 一个在线的 PornHub 风格 Logo 生成工具 Logoly.Pro ...