C#的好多定义跟C艹不太相同,先来分析一下“委托”。

1. 委托的定义:

  委托,可以认为是类型安全函数指针,类型安全就是指明确定义了返回类型与参数类型,在C#代码编译时就能够确保指针传参时的安全性。

  值得注意的是,委托也是一种类,在普遍的定义中,“类”表示广泛的定义,泛指一类事物,而对象则表示”类的实例”。但是委托只有一个术语,既表示“类”,也表示”实例”。

  委托类的定义主要是定义它函数指针的返回值、参数类型。委托类的实例化,则是将符合委托类定义的具体函数指针交给一个实例。

2. 委托的用法:

  简单的用法不加赘述,把它理解成类型安全的函数指针后就容易多了。

  简单的提示则是:

public delegate string GetString();

int x = 10;

GetString testmethod = new GetString(x.ToString);

  x.ToString 代表的才是函数指针,而不是 x.ToString(),它代表的只是 string 类型的返回值。

3. Action<T>与Func<T>:

   在C#代码阅读中,经常发现Action<T>与Func<T>的用法。

Action<T>:这类委托表示引用一个返回类型为void的方法。例如,Action<in T1, in T2> 表示调用带2个参数的方法。

Func<T>:这类委托表示引用一个带返回类型的方法。例如,Func<in T1, out T> 表示带一个参数且有返回类型的方法,out 永远放在最后一位。

  使用Action<T>与Func<T>可以一句话就包含了委托类型的定义与实例化:

    class MathOperation
{
public static double MultiplyByTwo(double value)
{
var res = value * 2;
Console.WriteLine("MultiplyByTwo:{0}.", res);
return res;
} public static void ProcessAndDisplay(Func<double, double> action, double value)
{
Console.WriteLine();
Console.WriteLine("ProcessAndDisplay called with value = {0}.", value);
double res = action(value);
}
} class Program
{
static void Main(string[] args)
{
Func<double, double> MathOperations = MathOperation.MultiplyByTwo; MathOperation.ProcessAndDisplay(MathOperations, 2);
Console.ReadLine();
}
}

  Func<double, double> MathOperations = MathOperation.MultiplyByTwo;

  在这里就无需先 delegate double MathOperations(double value) 的声明了。

4. 多播委托

    class MathOperation
{
public static double MultiplyByTwo(double value)
{
var res = value * 2;
Console.WriteLine("MultiplyByTwo:{0}.", res);
return res;
} public static double Square(double value)
{
var res = value * value;
Console.WriteLine("Square:{0}.", res);
return res; } public static void ProcessAndDisplay(Func<double, double> action, double value)
{
Console.WriteLine();
Console.WriteLine("ProcessAndDisplay called with value = {0}.", value);
double res = action(value);
}
} class Program
{
static void Main(string[] args)
{
Func<double, double> MathOperations = MathOperation.MultiplyByTwo;
MathOperations += MathOperation.Square; MathOperation.ProcessAndDisplay(MathOperations, 2);
MathOperation.ProcessAndDisplay(MathOperations, 5);
Console.ReadLine();
}
}

  执行结果:

  从结果可以看出,每个委托实例事实上可以包含多个方法,相当于“方法数组”,每次调用委托,都会按顺序将“方法数组”中的每个方法逐个执行过去。

  要注意的是,通过一个委托调用多个方法,只要其中一个方法抛出异常,那么整个委托就会停止了。

  这就是多播委托。

粗看C#委托的更多相关文章

  1. 粗看ES6之面向对象写法

    标签: es6 在es6以前,js没有类的概念,虽然有构造函数原型的方式用来做面向对向开发,但是对于书法并不是十分友好,而且对于继承实现也不是十分友好. es6引入class constructor ...

  2. 粗看ES6之JSON

    标签: es6 ES6新增JSON特性不是特别多,只是针对JSON某些情况下的写法上有一些优化: 当key值和value值对应变量名相同时 json对像中的方法书写 示例代码如下: <!DOCT ...

  3. 粗看ES6之字符串

    标签: javascript es6 字符串新增特性 新增二个方法 - startsWith/endsWith 字符串模板 - 反单引号的应用 startsWith 判断字符串以是否以某某开头,返回一 ...

  4. 粗看ES6之数组

    标签: javascript es6 数组新增方法 map(可以理解为是映射,以一定规则修改数组每一项并返回全新数组) reduce(可以理解为是汇总,一堆出来一个) filter(可以理解为过滤,筛 ...

  5. 粗看ES6之解构赋值

    标签: javascript es6 什么是解构赋值? 示例如下: <!DOCTYPE html> <html> <head> <meta charset=& ...

  6. 粗看ES6之函数

    标签: es6 javascript 箭头函数 ES6为了书写方便引入了函数的全新简写方式-箭头函数 <!DOCTYPE html> <html> <head> & ...

  7. 粗看ES6之变量

    标签: javascript var定义变量面临的问题 可以重复定义 无法限制变量不可修改 无块级作用域 ES6变量定义升级 新增let定义变量 新增const定义常量 let特性 有块级作用域 不可 ...

  8. 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的

    0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...

  9. C#中的线程一(委托中的异步)

    C#中的线程一(委托中的异步) 一.同步委托 我们平时所用的委托以同步居多,我们编写一个方法和相关委托进行演示: publicdelegatevoid DoSomethingDelegate(stri ...

随机推荐

  1. 敏捷开发 and 敏捷测试

    名词解释 agile: 敏捷的:灵活:敏捷开发. scrum: 扭打,混打:并列争球:参加并列争球. sprint:  冲刺,全速跑. backlog: 积压的工作:积压待办的事务. retrospe ...

  2. Redis的安装及配置

    Redis安装及主从配置   一.何为Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表) ...

  3. MYSQL用户权限管理学习笔记

    MYSQL 用户管理 1.权限表 MYSQL是一个多用户的数据库,MYSQL的用户可以分为两大类: (1)       超级管理员用户(root),拥有全部权限 (2)       普通用户,由roo ...

  4. dubbo服务+Spring事务+AOP动态数据源切换 出错

    1:问题描述,以及分析 项目用了spring数据源动态切换,服务用的是dubbo.在运行一段时间后程序异常,更新操作没有切换到主库上. 这个问题在先调用读操作后再调用写操作会出现. 经日志分析原因: ...

  5. js判断字符串是否包含指定的字符

    判断字符串是否包含指定字符是很常用的功能,比如说,注册时用户名限制不能输入"管理员",或者需要js判断url跳转链接是否包含某个关键词等-- <!DOCTYPE html&g ...

  6. MySQL更新时Error Code:1093和Error Code:1175的解决办法

    Error Code: 1093. You can't specify target table 'ws_product' for update in FROM clause 这个是我们在使用upda ...

  7. 不可错过的手机APP常见8种界面导航样式

    前言:相信每个移动开发project师都会遇到,当一个项目开发启动时,须要考虑搭建怎么的框架.一个好的框架.也会决定着一个APP的前途与命运.框架的风格,如今常见的有八种:标签导航.舵式导航.抽屉导航 ...

  8. [PWA] 14. Loop cursor

    import idb from 'idb'; var dbPromise = idb.open('test-db', 4, function (upgradeDb) { switch (upgrade ...

  9. 将JDBC ResultSet结果集变成List

    private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>() ...

  10. Android Studio 快捷键(转)

    Android Studio 快捷键 操作 Mac OSX Win/Linux 注释代码(//) Cmd + / Ctrl + / 注释代码(/**/) Cmd + Option + / Ctrl + ...