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服务,开启是服务器会提示你设置独立密码,这个密码是跟邮箱正常登陆的密码不同的,这个是 ...
随机推荐
- xml解析-jaxp修改结点
jaxp修改结点 / 修改第一个p1下面的sex内容是nan * 1.创建解析器工厂 * 2.根据解析器工厂创建解析器 * 3.解析xml返回document * 4.得到sex item方法 * 5 ...
- log4cxx日志库在Windows+VS2017上的编译使用
项目中用到了log4cxx,但是Debug版本运行时老是提示找不到Properities::setProperty?怀疑是提供的库有问题,所以尝试源码来重新编译一下.log4cxx官方主页:https ...
- 使用JS通过Web API执行批量操作,多个操作是一个事务!
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复235或者20161105可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...
- gradle使用基础
说明 介绍gradle使用基础,gradle基础脚本结构和常规使用方法,以及一个简单的gradle示例.主要是为了简单的介绍gradle使用. gradle环境配置 gradle可以通过两种方式运行g ...
- DevOps 工程师成长日记系列三:版本
原文地址:https://medium.com/@devfire/how-to-become-a-devops-engineer-in-six-months-or-less-part-3-versio ...
- [Go] 利用channel实现简单的工作池
先启动固定数量的goroutine,每个goroutine都在从channel中获取数据,如果这个channel为空,就阻塞等待在那里channel中传递一个Car类型,这个类型主要负责具体做的任务也 ...
- Linux 的 netstat 命令
转载 https://www.cnblogs.com/ct20150811/p/9432043.html 一般用 netstat -lnp |grep "程序名"
- Pwn-level1
题目地址 https://dn.jarvisoj.com/challengefiles/level1.80eacdcd51aca92af7749d96efad7fb5 先看一下文件的类型和保护机制 ...
- LG3237 「HNOI2014」米特运输 树形DP
问题描述 LG3237 题解 问题转化为: 要求将这棵树,满足 结点 \(x\) 所有孩子权值相等 结点 \(x\) 权值等于所有孩子权值和 将乘法转化为 \(\log\) 加法 \(\mathrm{ ...
- CF915E Physical Education Lessons 珂朵莉树
问题描述 CF915E LG-CF915E 题解 \(n \le 10^9\) 看上去非常唬人. 但是这种区间操作的题,珂朵莉树随便跑啊. \(\mathrm{Code}\) #include< ...