当前位置:网站首页>C#-委托的详细用法
C#-委托的详细用法
2022-08-11 00:30:00 【真的没事鸭】
什么是委托
委托是一种函数引用的Object,实际上是用类完成了函数指针的功能
C#中的委托(Delegate)类似于C或C++中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。
委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生 自System.Delegate 类。
委托的使用
1,声明委托:
Delegate void Print(int x)
2,初始化,给委托赋值
- 方法1:Print someFunc=hello;
- 方法2:Print someFunc=new Print(hello);
3,调用委托变量
SomeFunc(x);
委托的分类
- 委托静态方法:委托一个静态方法
- 委托实例方法:委托一个实例方法
委托的原理
委托是将函数指针和实例对象打包在一起的类,它有两个重要的成员,一个用来保存实例对象,一个用来保存函数的指针。从源码中可以查看System.Delegate

我们查看System.Delegate的属性,可以看到一个属性Target
public Object Target
{
get
{
return GetTarget();
}
}看一下GetTarget的功能
internal virtual Object GetTarget()
{
return (_methodPtrAux.IsNull())?_target:null;
}意思就是当把一个静态方法给委托的时候将会返回一个null,如果是一个实例方法时, 将会返回当前方法所在的实例对象(this)
下面用一段代码演示一下:
using System;
//声明委托
public delegate void Print();
namespace ConsoleApp1
{
public class Test
{
//实例方法
public void Test1()
{
Console.WriteLine("这是实例方法!");
}
//静态方法
public static void Test2()
{
Console.WriteLine("这是静态方法!");
}
}
class Program
{
static void Main(string[] args)
{
//委托的使用
Test t = new Test();//实例对象
Print p1 = new Print(t.Test1);//委托赋值-实例方法
p1();//调用委托
Print p2 = new Print(Test.Test2);//委托赋值-静态方法
p2();//调用委托
//委托原理
Console.WriteLine(p1.Target is Test);//实例方法-判断Target是不是指向方法所在的对象
Console.WriteLine(p2.Target is Test);//静态方法-判断Target是不是null
Console.ReadLine();
}
}
}
输出结果
这是实例方法!
这是静态方法!
True
False也就是如果Target属性为null说明是静态方法的委托,如果不为null说明是实例方法的 委托
需要注意的是声明的委托类型和被委托的函数类型以及参数要一致,如果委托没有返回 值,那么被委托的函数也要没有返回值,如果委托有参数,那么被委托的函数和委托的 参数类型要一致。
通过这个代码就可以很直白的看出委托的作用,就是将方法封装在委托中,然后就可以将委托对象传递给可调用所引用方法的代码,不必在编译时知道将要调用那个方法。
系统内置委托
前面是自己定义的委托,但是系统也提供了两种委托:Action和Func,Action用于不需 要返回值的委托,Func适合需要返回值的委托
Action委托
1,Action委托 封装一个方法,该方法不具有参数并且不返回值
2,Action<T>委托 封装一个方法,该方法只有一个参数并且不返回值
3,Action<T1,T2>委托 封装一个方法,该方法具有两个参数并且不返回值
最多有16个参数
Func委托
1,Func(TResult)委托封装封装一个不具有参数但却返回 TResult 参数指定的类型值的方 法
2,Func(T,TResult)委托 封装一个具有一个参数并返回 TResult 参数指定的类型值的方法
3,Func(T1,T2,TResult)委托 封装一个具有两个参数并返回 TResult 参数指定的类型值的方 法
其中的T是参数类型,TResult是返回值类型
下面用一个例子演示:
using System;
namespace ConsoleApp1
{
public class Test
{
//Action示例
public void Test1()
{
Console.WriteLine("这是Action示例!");
}
//Func示例
public int Test2(int n)
{
return n;
}
}
class Program
{
static void Main(string[] args)
{
//系统内置委托的使用
Test t = new Test();//实例对象
Action ac1=new Action(t.Test1);//委托赋值
ac1();//调用委托
Func<int,int> ac2 = new Func<int,int>(t.Test2);//委托赋值
Console.WriteLine(ac2(233));//调用委托
Console.ReadLine();
}
}
}
输出结果:
这是Action示例!
233多播委托
多播委托是指在一个委托中注册多个方法,在注册方法时可以在委托中使用加号运算符
或者减号运算符来实现添加或撤销方法。
比如现实的点餐系统,可以点甜食,面食,水果等,在这里委托相当于点餐平台,每一 个类型的商品可以理解为在委托商注册的一个方法。
using System;
//声明委托
public delegate void Order();
namespace ConsoleApp1
{
public class Test
{
//买水果
public void Test1()
{
Console.WriteLine("购买水果!");
}
//买甜食
public static void Test2()
{
Console.WriteLine("购买甜食!");
}
}
class Program
{
static void Main(string[] args)
{
//多播委托
Test t = new Test();//实例对象
Order order=new Order(t.Test1);//委托赋值-实例方法
order();//调用委托
Order order1 = new Order(Test.Test2);//委托赋值-静态方法
order1();
Console.ReadLine();
}
}
}
输出结果:
购买水果!
购买甜食!在使用多播委托时需要注意,在委托中注册的方法参数列表必须与委托定义的参数列表 相同,否则不能将方法添加到委托上。
如有错漏之处,敬请指正!
边栏推荐
- ADC和DAC记录
- 14. Thymeleaf
- Web APIs BOM- 操作浏览器之综合案例
- In 22 years, the salary of programmers nationwide in January was released, only to know that there are so many with annual salary of more than 400,000?
- 李彦宏拆墙交朋友,大厂“塑料友情”能否帮百度啃下硬骨头?
- SAP ABAP JSON 格式数据处理
- Distributed. Performance optimization
- [Excel knowledge and skills] Convert numeric format numbers to text format
- 91.(cesium之家)cesium火箭发射模拟
- Design and Realization of Employment Management System in Colleges and Universities
猜你喜欢

SAS data processing technology (1)

Why do programming languages have the concept of variable types?

盘点美军的无人机家底

"NIO Cup" 2022 Nioke Summer Multi-School Training Camp 3 DF Problem Solving

报错:Client does not support authentication protocol requested by server; consider upgrading MySQL cli

微信小程序自定义navigationBar

Software Testing Certificate (1) - Software Evaluator

16. File upload

input输入框超出部分用省略号表示以及判断内容是否有超出(PC端)

镜头之滤光片---关于日夜两用双通滤光片
随机推荐
从0开始设计JVM ,忘记名词跟上思路一次搞懂
[Excel knowledge and skills] Convert numeric format numbers to text format
[Data Visualization] Chart Design Principles
YOLOv5的Tricks | 【Trick12】YOLOv5使用的数据增强方法汇总
HGAME 2022 Final Pokemon v2 writeup
UOJ#749-[UNR #6]稳健型选手【贪心,分治,主席树】
学习Apache ShardingSphere解析器源码(一)
15. Interceptor - HandlerInterceptor
关于编程本质那些事
【考虫 六级英语】语法课笔记
Dump文件生成,内容,以及分析
HW-蓝队工作流程(1)
【pypdf2】安装、读取和保存、访问页面、获取文本、读写元数据、加密解密
【js】获取当前时间的前后n天或前后n个月(时分秒年月日都可)
如何破坏Excel文件,让其显示文件已损坏方法
“蔚来杯“2022牛客暑期多校训练营3 DF题解
虚拟电厂可视化大屏,深挖痛点精准减碳
"NIO Cup" 2022 Nioke Summer Multi-School Training Camp 2 DGHJKL Problem Solution
ADC和DAC记录
云原生-VMware虚拟机安装Kubesphere实战(一)