C# 委托补充01
上一篇文章写了委托的最基本的一些东西,本篇咱们扯扯委托其他的东西。
示例1插件编程
根据对委托的理解,委托可以把一个方法当作参数进行传递,利用这个特性我们可以使用委托,实现插件编程。
public delegate int Transformer(int x);
class Util{
pubilc static void Transform(int[] values, Transformer t){
for(int i = 0; i < values.Length; i++){
values[i] = t?.Invke(values[i]);
}
}
}
class Test{
static void Main(){
int[] values = {1,2,3};
Util.Transform(values, Sqare);
foreach(int i in values){
Console.WriteLine(i + " "); //1 4 9
}
}
static int Sqare (int x) => x * x;
}
这里的Transform方法就是插件方法,它接受一个委托参数。
示例2多播委托
所有的委托都有多播的能力。这就意味着一个委托可以引用一个方法,或者引用一个组方法。委托使用 += 和 -=运算符联结多个委托实例。
public class People{}
public class Student:People{}
public delegate void Action();
class Program
{
static void Say(){
Console.WriteLine("Say HI");
}
static void Write(){
Console.WriteLine("Write Anything");
}
Action action = Say;
action += Write;//action = action + Write;
action();
/*
Say HI
Write Anything
*/
}
委托会按照添加的顺序依次触发。如果存在返回值,那么调用者会将最后一个带有非void返回值类型的方法返回值进行返回,其他的返回值将会抛弃。
- 和-= 运算符会从左侧委托操作数中将右侧的委托操作删除。
对于为值为null的委托执行 + 或者+= 操作,等价于为委托指定一个新的值。同样在当委托只有一个目标方法时,执行-=操作等价于为委托指定null值。
由于委托是一个类,所以委托是不可变,每次执行 += 或者-= 实质上等价于从新创建一个新的委托实例,并为它赋值。
具体使用,比如说我们要建一栋大楼,需要很长一段时间,但是公司有要求每建好一层需要给公司汇报一下。
public delegate void ProgressReporter(int floor);
public class Edifice{
public static void Build(ProgressReporter p){
for(int i = 0; i < 18; i++){
p(i);
System.Threading.Thread.Sleep(1000);//添加点时间
}
}
}
class Test{
static void Main(){
ProgressReporter p = WriteProgressToConsole;
p += AdviseToCompany;
Edifice.Build(p);
}
static void WriteProgressToConsole(int fool) => Console.WriteLine($"{fool}层已建成");
static void AdviseToCompany(int fool) => Console.WriteLine($"**项目,已经建好{fool}层。");
}
示例3泛型委托
委托类型可以包含泛型类型参数,如:
public delegate T Transformer<T> (T t);
通过一个泛型参数,我们可以定义一个通用的Transformer,让它对任何类型都有效:
public class util{
public static void Transform<T> (T[] values, Transformer<T> t){
for(int i = 0; i < values.Length; i++){
values[i] = t(values[i]);
}
}
}
class Test{
static void Main(){
int[] values = {1,2,3};
Util.Transformer(values, Square);
foreach(int i in values){
Console.Write(i + " "); //1 4 9
}
}
static int Sqare (int x) => x * x;
}
既然委托支持泛型参数,那么就可以定义一些小型的委托类型,它们可以具有任意的返回类型和合理的数目的参数,类如系统定义好的Action委托和Func委托(out和in标记可变性修饰符,在逆变和协变中有解释)。
delegate void Action();
delegate void Action<in T> (T arg);
delegate void Action<in T1, in T2> (T1 arg1, T2 arg2)
………
delegate TResule Func(out TResule)();
delegate TResule Func<in T, out TResule> (T arg);
delegate TResule Func<in T1, in T2, out TResule> (T1 arg1, T2 arg2)
………
其中Action和Func 都可以支持16个参数。
上面的Transform重写.
public static void Transform<T> (T[] values, Func<T, T> transformer){
for(int i = 0; i < values.Length; i++){
values[i] = transformer(values[i]);
}
}
委托还有很多东西,下次聊!
参考自C#7.0核心技术指南
C# 委托补充01的更多相关文章
- Python补充01 序列的方法
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在快速教程中,我们了解了最基本的序列(sequence).回忆一下,序列包含有定值 ...
- 【Python 补充01】Python运算符
Python运算符 举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. 1.算术运算符 + - * / # 加减乘除 % # 取模(返回除 ...
- 第三课补充01——set类型 sorted类型命令操作详解,redis管道及事务
1. set类型的命令操作: (1)sadd命令:向key指定的set集合添加成员 ##sadd命令:是设置set集合类型的数据,sadd <key> <mumber> [& ...
- 第二课补充01——redis-cli命令行详解、string类型、list类型、hash类型命令操作详解
一. redis-cli命令行参数 1.-x参数:从标准输入读取一个参数: [问题] [解决] 因为echo命令是默认带有回车\n的,不带回车需要echo –n命令: echo -n "ha ...
- 补充01 Django 类视图
视图 函数视图[Function Base View] 以函数的方式定义的视图称为函数视图,函数视图便于理解.但是遇到一个视图对应的路径提供了多种不同HTTP请求方式的支持时,便需要在一个函数中编写不 ...
- python教程与资料
网上有个人写的python快速教程,非常好.比看书好多了.猛击下面的链接地址 http://www.douban.com/group/topic/30008503/ python文档资料收集 pyth ...
- 【Python大系】Python快速教程
感谢原作者:Vamei 出处:http://www.cnblogs.com/vamei 怎么能快速地掌握Python?这是和朋友闲聊时谈起的问题. Python包含的内容很多,加上各种标准库.拓展库, ...
- Python快速教程目录(转)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 怎么能快速地掌握Python?这是和朋友闲聊时谈起的问题. Python包含的内容 ...
- java实现smtp邮件发送
一.准备工作 首先你需要已一个发送邮箱,一般的邮箱都有SMTP.POP3服务,比如QQ邮箱,登陆QQ邮箱开启SMTP服务,开启是服务器会提示你设置独立密码,这个密码是跟邮箱正常登陆的密码不同的,这个是 ...
随机推荐
- SPA项目开发之首页导航+左侧菜单
Mock.js: 前后端分离之后,前端迫切需要一种机制,不再需要依赖后端接口开发,而mockjs就可以做到这一点 Mock.js是一个模拟数据的生成器,用来帮助前端调试开发.进行前后端的原型分离以及用 ...
- fwrite(): send of 8192 bytes failed with errno=104 Connection reset by peer
问题:fwrite(): send of 8192 bytes failed with errno=104 Connection reset by peer 问题描述 通过mysql + sphinx ...
- 数据库系统原理(第四章:SQL与关系数据库基本操作 )
一.SQL概述 sql是结构化查询语言(Structured Query Language,SQL)是专门用来与数 据库通信的语言,它可以帮助用户操作关系数据库. SQL的特点: SQL不是某个特定数 ...
- RiscV汇编介绍(2)-编译过程
elf文件全称是Executable and Linkable Format,可执行链接格式,elf文件中除了机器码之外,还有段加载地址,运行入口地址,数据段等. elf文件格式主要有以下三种: 可重 ...
- react 地图发布 cesium 篇
上篇文章介绍了如何搭建 react cesium 开发环境.在开发环境下,项目一切运行正常.最近把项目打包发布出来,却遇见了 cesium 不能正确初始化.打开浏览器的调试面板,出现好多 404,资源 ...
- LayoutSubviews的调用
1.当view被添加到另一个view上时调用 2.布局子控件时调用 3.屏幕旋转的时候调用 4.当view的尺寸大小改变的时候调用
- switch...case...语句分析(大表跟小表何时产生)
一.switch...case...的格式 switch(表达式) { case 常量表达式1: 语句; break; case 常量表达式2: 语句; break; case 常量表达式3: 语句; ...
- 基于tiny4412的Linux内核移植 --- aliases节点解析【转】
转自:https://www.cnblogs.com/pengdonglin137/p/5252348.html 阅读目录(Content) 作者信息 平台简介 正文 回到顶部(go to top) ...
- Android刷机
1.安装第三方recovery 下载自己手机适配的recovery包 https://twrp.me/lg/lgnexus5.html fastboot 卡在 waiting for device $ ...
- Java学习笔记(4)--- 变量类型,修饰符
1.变量类型: a.定义: 和C++差不多,就是: type identifier [ = value][, identifier [= value] ...]: type为Java数据类型.iden ...