浅谈C#委托的用法-delegate
2018年11月7日 小雨
一、委托的概念
委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行。
借用百度上的一句话概括:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,
可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
二、委托的声明
与对应的方法具有相同的参数类型、参数个数、返回值。通俗来讲就是“函数的模板原型”。
三、委托的使用
- 用delegate声明一个委托
- 委托实例化
- 调用
public class DelegateClass
{
public delegate void DelegateTest(int a, int b); //1、声明一个委托 public static void Test()
{
DelegateTest method = new DelegateTest(Plus); //2、实例化委托
//DelegateTest method1 = Plus; //实例化委托的另一种等价写法
method.Invoke(, ); //3、调用
//method1(3, 4); //调用的另一种等价写法
} private static void Plus(int a, int b)
{
Console.WriteLine("a={0} b={1}", a, b);
}
}
四、委托的意义
1、没有委托就没有异步
2、解耦
3、高效扩展
public class CallStudent
{
//方法1
public static void CallStudentA(string name)
{
Console.WriteLine("{0}", name);
}
//方法2
public static void CallStudentB(string name)
{
Console.WriteLine("{0}", name);
}
//方法3
public static void CallStudentC(string name)
{
Console.WriteLine("{0}", name);
} //传值的方式,根据值来决定行为,所有的方法全部耦合在一起,
//如果要增加方法则需要修改该方法,不便于方法的封装、扩展
public static void CallStudentName(string name, StudentType type)
{
if (type == StudentType.A)
{
Console.WriteLine("{0}", name);
}
else if (type == StudentType.B)
{
Console.WriteLine("{0}", name);
}
else if (type == StudentType.C)
{
Console.WriteLine("{0}", name);
}
} //用委托的方式来实现传递方法,如果要增加方法,只需要重新增加一个方法就好
public static void CallStudentName(string name, CallStudentHandler handler)
{
handler.Invoke(name);
}
} public delegate void CallStudentHandler(string name); public enum StudentType
{
A,
B,
C
}
static void Main(string[] args)
{
//用不同的值来区分不同的方法
CallStudent.CallStudentName("Student A",StudentType.A );
CallStudent.CallStudentName("Student B", StudentType.B);
CallStudent.CallStudentName("Student C", StudentType.C );
Console.WriteLine(); //用委托的方式传递多个方法
CallStudentHandler handlerA = new CallStudentHandler(CallStudent.CallStudentA);
CallStudent.CallStudentName("Student A", handlerA); CallStudentHandler handlerB = new CallStudentHandler(CallStudent.CallStudentB);
CallStudent.CallStudentName("Student B", handlerB); CallStudentHandler handlerC = new CallStudentHandler(CallStudent.CallStudentC);
CallStudent.CallStudentName("Student C", handlerC);
Console.WriteLine(); //用匿名函数的方法替代上述写法
CallStudentHandler handler1 = new CallStudentHandler(
delegate(string name)
{
Console.WriteLine("{0}", name);
}); //用匿名的方式把方法名给去掉
handler1.Invoke("Student A"); //用lambda表达式的方式1 替代上述写法
//Lambda表达式的本质就是一个匿名方法
CallStudentHandler handler2= new CallStudentHandler(
(string name)=>
{
Console.WriteLine("{0}", name);
}); //用lambda表达式的方式把delegate换成=> 箭头左边是参数列表,右边是方法体
handler2.Invoke("Student A"); //用lambda表达式的方式2
CallStudentHandler handler3 = new CallStudentHandler(
(name) =>
{
Console.WriteLine("{0}", name);
}); //去掉参数类型
handler3.Invoke("Student A"); //用lambda表达式的方式3
CallStudentHandler handler4 =(name) =>
{
Console.WriteLine("{0}", name);
}; //去掉 new CallStudentHandler
handler4.Invoke("Student A"); //用lambda表达式的方式4
CallStudentHandler handler5 = (name) => Console.WriteLine("{0}", name); //去掉{},适用于方法体只有一行
//去掉{}后,如果方法体只有一行,带返回值的去掉return
handler5.Invoke("Student A"); Console.ReadLine();
}
浅谈C#委托的用法-delegate的更多相关文章
- 浅谈C#委托的用法-delegate[转]
一.委托的概念 委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行. 借用百度上的一句话概括:委托是一个类,它定义了方 ...
- 浅谈C#委托和事件
委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...
- 浅谈C#委托和事件【转】
委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...
- 浅谈C#委托和事件(转载)
委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...
- 浅谈 C#委托
看了<CLR via C#>的17章委托后,为自己做一点浅显的总结,也分享给需要的人. .NET通过委托来提供一种回调函数机制,.NET委托提供了很多功能,例如确保回调方法是类型安全的(C ...
- 【Python学习笔记之二】浅谈Python的yield用法
在上篇[Python学习笔记之一]Python关键字及其总结中我提到了yield,本篇文章我将会重点说明yield的用法 在介绍yield前有必要先说明下Python中的迭代器(iterator)和生 ...
- 浅谈final关键字的用法
1.final变量: 常和static一起使用,修饰成员变量或者本地变量.修饰后为常量,不可以再次初始化(再次引用),例如public static final String SUCCESS= &qu ...
- 浅谈async函数await用法
今天状态不太好,睡久了懵一天. 以前只是了解过async函数,并还没有很熟练的运用过,所以先开个坑吧,以后再结合实际来更新下,可能说的有些问题希望大家指出. async和await相信大家应该不陌生, ...
- 浅谈java中bigInteger用法
1.赋值: BigInteger a=new BigInteger("1"); BigInteger b=BigInteger.valueOf(1); 2.运算: ① add(); ...
随机推荐
- Python爬虫实战教程:爬取网易新闻;爬虫精选 高手技巧
前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. stars声明很多小伙伴学习Python过程中会遇到各种烦恼问题解决不了.为 ...
- SWIG 3 中文手册——10. 参数处理
目录 10 参数处理 10.1 typemaps.i 库 10.1.1 引言 10.1.2 输入参数 10.1.3 输出参数 10.1.4 输入 / 输出参数 10.1.5 使用不同的名称 10.2 ...
- 剑指offer-面试题59_1-滑动窗口的最大值-数组
/* 题目: 链接:https://www.nowcoder.com/questionTerminal/1624bc35a45c42c0bc17d17fa0cba788 来源:牛客网 给定一个数组和滑 ...
- Python学习记录(一):Anaconda3的安装、配置与使用
简单说下为啥要创建Python虚拟环境呢? 不同的Python工程中用到的包不尽相同,相同包的版本也可能不一样,一种方法是使得各个环境相对独立. 假如说某一个环境崩了,直接remove掉就可以了,不会 ...
- vue-infinite-loading 过滤器tab正确使用
业务逻辑涉及loadmore,filter和tab切换,框架是vue,使用vue-infinite-loading中的一点经历. identifier 一开始并没有重视这个参数,只是他的官网说iden ...
- jrtp 使用
jrtplib-3.11.1 使用jthread-1.3.3 # cmake 下载https://cmake.org/download/ 使用地址https://github.com/j0r1/JRT ...
- [HNOI2015]接水果[整体二分]
[HNOI2015]接水果 给出一个树上路径集合\(S\) 多次询问\(x,y\)中的\(k\)小值 如果你问我数列上那么我会 树上的话 树上差分了吧直接?- 令 \(st_x<st_y\) 1 ...
- 洛谷【P5004 专心OI - 跳房子】 题解
题目链接 https://www.luogu.org/problem/P5004 洛谷 P5004 专心OI - 跳房子 Imakf有一天参加了PINO 2017 PJ组,他突然看见最后一道题 他十分 ...
- Android 存档最优选项
1 开发环境:VS2019最新版本(16.4.5) 2 存档最优选项 说明:apk包70M(默认选项),apk包12M(调整后选项) 位置:Android 选项
- 分布式集群HA模式部署
一:HDFS系统架构 (一)利用secondary node备份实现数据可靠性 (二)问题:NameNode的可用性不高,当NameNode节点宕机,则服务终止 二:HA架构---提高NameNode ...