粗看C#委托
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#委托的更多相关文章
- 粗看ES6之面向对象写法
标签: es6 在es6以前,js没有类的概念,虽然有构造函数原型的方式用来做面向对向开发,但是对于书法并不是十分友好,而且对于继承实现也不是十分友好. es6引入class constructor ...
- 粗看ES6之JSON
标签: es6 ES6新增JSON特性不是特别多,只是针对JSON某些情况下的写法上有一些优化: 当key值和value值对应变量名相同时 json对像中的方法书写 示例代码如下: <!DOCT ...
- 粗看ES6之字符串
标签: javascript es6 字符串新增特性 新增二个方法 - startsWith/endsWith 字符串模板 - 反单引号的应用 startsWith 判断字符串以是否以某某开头,返回一 ...
- 粗看ES6之数组
标签: javascript es6 数组新增方法 map(可以理解为是映射,以一定规则修改数组每一项并返回全新数组) reduce(可以理解为是汇总,一堆出来一个) filter(可以理解为过滤,筛 ...
- 粗看ES6之解构赋值
标签: javascript es6 什么是解构赋值? 示例如下: <!DOCTYPE html> <html> <head> <meta charset=& ...
- 粗看ES6之函数
标签: es6 javascript 箭头函数 ES6为了书写方便引入了函数的全新简写方式-箭头函数 <!DOCTYPE html> <html> <head> & ...
- 粗看ES6之变量
标签: javascript var定义变量面临的问题 可以重复定义 无法限制变量不可修改 无块级作用域 ES6变量定义升级 新增let定义变量 新增const定义常量 let特性 有块级作用域 不可 ...
- 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的
0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...
- C#中的线程一(委托中的异步)
C#中的线程一(委托中的异步) 一.同步委托 我们平时所用的委托以同步居多,我们编写一个方法和相关委托进行演示: publicdelegatevoid DoSomethingDelegate(stri ...
随机推荐
- 敏捷开发 and 敏捷测试
名词解释 agile: 敏捷的:灵活:敏捷开发. scrum: 扭打,混打:并列争球:参加并列争球. sprint: 冲刺,全速跑. backlog: 积压的工作:积压待办的事务. retrospe ...
- Redis的安装及配置
Redis安装及主从配置 一.何为Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表) ...
- MYSQL用户权限管理学习笔记
MYSQL 用户管理 1.权限表 MYSQL是一个多用户的数据库,MYSQL的用户可以分为两大类: (1) 超级管理员用户(root),拥有全部权限 (2) 普通用户,由roo ...
- dubbo服务+Spring事务+AOP动态数据源切换 出错
1:问题描述,以及分析 项目用了spring数据源动态切换,服务用的是dubbo.在运行一段时间后程序异常,更新操作没有切换到主库上. 这个问题在先调用读操作后再调用写操作会出现. 经日志分析原因: ...
- js判断字符串是否包含指定的字符
判断字符串是否包含指定字符是很常用的功能,比如说,注册时用户名限制不能输入"管理员",或者需要js判断url跳转链接是否包含某个关键词等-- <!DOCTYPE html&g ...
- MySQL更新时Error Code:1093和Error Code:1175的解决办法
Error Code: 1093. You can't specify target table 'ws_product' for update in FROM clause 这个是我们在使用upda ...
- 不可错过的手机APP常见8种界面导航样式
前言:相信每个移动开发project师都会遇到,当一个项目开发启动时,须要考虑搭建怎么的框架.一个好的框架.也会决定着一个APP的前途与命运.框架的风格,如今常见的有八种:标签导航.舵式导航.抽屉导航 ...
- [PWA] 14. Loop cursor
import idb from 'idb'; var dbPromise = idb.open('test-db', 4, function (upgradeDb) { switch (upgrade ...
- 将JDBC ResultSet结果集变成List
private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>() ...
- Android Studio 快捷键(转)
Android Studio 快捷键 操作 Mac OSX Win/Linux 注释代码(//) Cmd + / Ctrl + / 注释代码(/**/) Cmd + Option + / Ctrl + ...