C#关于Func和Action委托的介绍详解
作者:风,停下 发布时间:2022-10-13 04:43:14
委托:委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。
委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。
1.Action委托
没有返回值,可以不包含参数
(1)声明委托、定位委托事件、向委托添加事件、执行委托
/// <summary>
/// 不包含参数
/// </summary>
private event Action Action_0;
/// <summary>
/// 包含一个参数
/// </summary>
private event Action<int> Action_1;
/// <summary>
/// 包含两个参数
/// </summary>
private event Action<int, double> Action_2;
/// <summary>
/// 包含三个参数
/// </summary>
private event Action<int, double, string> Action_3;
/// <summary>
/// 定义没有参数委托的事件
/// </summary>
private void Fun_0()
{
Console.WriteLine("没有参数");
}
/// <summary>
/// 定义包含一个参数委托的事件
/// </summary>
private void Fun_1(int nInt)
{
Console.WriteLine($"包含一个参数:{nInt}");
}
/// <summary>
/// 定义包含两个参数委托的事件
/// </summary>
private void Fun_2(int nInt, double dDouble)
{
Console.WriteLine($"包含两个参数,参数值:{nInt},{dDouble}");
}
/// <summary>
/// 定义包含三个参数委托的事件
/// </summary>
private void Fun_3(int nInt, double dDouble, string str)
{
Console.WriteLine($"包含三个参数,参数值:{nInt},{dDouble},{str}");
}
//点击事件
private void btn_Click(object sender, EventArgs e)
{
//向委托添加事件
Action_0 += Fun_0;
Action_1 += Fun_1;
Action_2 += Fun_2;
Action_3 += Fun_3;
//执行委托
Action_0.Invoke();
Action_1.Invoke(666);
Action_2.Invoke(666,888.0);
Action_3.Invoke(666,888,"Hello World");
}
输出结果:
由于btn_Click为点击事件,点击第二次(第二次点击会再次向委托添加事件)的数据结果如下:
因此,向委托添加事件时,一个事件仅添加一次即可,若进行多次添加则调用委托时会将添加进入委托的所有事件进行调用,无论该事件是否已添加都会进行调用,故做如下处理(在构造函数中或在程序启动时添加委托事件):
上图中委托调用时提示波浪线,因为是委托在调用时可能未添加事件,将会抛出:未将对象引用设置到对象的实例的异常信息,
异常信息:
故调用时进行异常处理或做如下处理:
处理方案1:
private void button1_Click(object sender, EventArgs e)
{
Action_0?.Invoke();
Action_1?.Invoke(666);
Action_2?.Invoke(666, 888.0);
Action_3?.Invoke(666, 888, "Hello World");
}
处理方案2
//执行委托
private void button1_Click(object sender, EventArgs e)
{
try
{
Action_0.Invoke();
Action_1.Invoke(666);
Action_2.Invoke(666, 888.0);
Action_3.Invoke(666, 888, "Hello World");
}
catch (Exception ex)
{
MessageBox.Show("调用出现异常", "提示");
}
}
此时,我们已经学会了Action委托的简单使用,这时会有人考虑到,我想调用完返回信息Action委托并没有返回,会限制我们的使用,不要着急,我们系统已经帮我们准备了一个现成的委托类型Func,下面我们对Func做个介绍。
2.Func委托
话不多说,上代码,以下我们定义了包含两个参数int和double,返回值为string类型的Func委托,并添加了两个事件Fun_1和Fun_2:
public partial class Form1 : Form
{
/// <summary>
/// 包含两个参数int和double,返回值为string类型委托
/// </summary>
private event Func<int, double, string> TestFunc;
/// <summary>
/// 定义委托的事件
/// </summary>
private string Fun_1(int nInt, double dDouble)
{
Console.WriteLine($"参数值:{nInt},{dDouble}");
return "事件:Fun_1";
}
/// <summary>
/// 定义委托的事件
/// </summary>
private string Fun_2(int nInt, double dDouble)
{
Console.WriteLine($"参数值:{nInt},{dDouble}");
return "事件:Fun_2";
}
/// <summary>
/// 窗体构造函数
/// </summary>
public Form1()
{
InitializeComponent();
InitAction();
}
//向委托添加事件
private void InitAction()
{
TestFunc += Fun_1;
TestFunc += Fun_2;
}
//执行委托
private void button1_Click(object sender, EventArgs e)
{
var result = TestFunc?.Invoke(888, 10);
Console.WriteLine($"返回结果:{result}");
}
}
输出结果:
从输出结果不难看出向委托添加多个事件(委托的多播或组播),委托包含返回值时,仅得到最后向委托添加的事件(方法)的返回值,所以在使用有返回值时必须注意这一点。
以下为先添加Fun_2后添加Fun_1的返回结果:
到这里,委托的介绍我们已经介绍完了,更多相关C# Func 和Action 委托内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://blog.csdn.net/weixin_47492910/article/details/122959045


猜你喜欢
- 栈的变化规则:1、方法调用会导致栈的生长,具体包括两个步骤:一、插入方法返回地址(下图中的Fn:);二、将实际参数按值(可以使用ref或ou
- Android直播软件搭建实现背景颜色滑动渐变效果的相关代码一、介绍一下GradientDrawableGradientDrawable 支
- 前言上一篇分析了事务注解的解析过程,本质上是将事务封装为切面加入到AOP的执行链中,因此会调用到MethodInceptor的实现类的inv
- 前 言终于来到下篇了,通过上篇,和中篇,我们了解了linq的基本语句,对应linq我们又了解到lambda表达式,静态扩展方法,以及linq
- 弃用内容先来纠正一个误区。主要之前在版本更新介绍的时候,存在一些表述上的问题。导致部分读者认为这次的更新是Datasource本身初始化的调
- 具体代码如下所示:/// <summary> /// 启用事务提交多条带参数的SQL语句 /// </summary>
- 最近开发了比较多的接口,因为没有可参考的案例,所以一开始一直按照我的理解进行开发。开发多了发现自己每个结果都写了相同的代码:try() {}
- 之前给大家在博文中讲过如何通过eclipse快速搭建SSM开发环境,但相对而言还是有些麻烦的,今天玄武老师给大家介绍下如何使用Intelli
- 本文介绍WPF一种自定义按钮的方法。实现效果使用图片做按钮背景;自定义鼠标进入时效果;自定义按压效果;自定义禁用效果实现效果如下图所示:实现
- 1.前言热修复一直是这几年来很热门的话题,主流方案大致有两种,一种是微信Tinker的dex文件替换,另一种是阿里的Native层的方法替换
- 一条SQL使用两个foreach的问题未修改前的 SQL 语句<select id="findQuestionType_3_
- 1.相关概念Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性。建
- 前言大部分来自:https://blog.csdn.net/justloveyou_/article/details/61672133。并在
- 本文实例为大家分享了Handler实现倒计时功能的具体代码,供大家参考,具体内容如下1、需求1.1 实现目标当后台传递一个时间戳时,与当前系
- BitArray的基础可以看菜鸟编程BitArray 类管理一个紧凑型的位值数组,它使用布尔值来表示,其中 true 表示位是开启的(1),
- 如何实现使用TextView的DrawableLeft使图片和文字居中显示呢???代码如下: 1.首先自定义一个类,继承TextViewpa
- 一、布局文件part.xml:<RelativeLayout xmlns:android="http://schemas.a
- Spring整合mybatis的mapper生成过程mapperScannerConfigurer实现了BeandifinitionRegi
- 本文实例为大家分享了Unity调取移动端的麦克风进行录音并播放的具体代码,供大家参考,具体内容如下1.对MicroPhone类的理解对麦克风
- 之前看到过一个数字进度条,一直想写,今天就把这个实现下,想起来也是很简单的,先看下实现的效果:思路:绘制2根线 绘制进度条的文字,不断的改变