C#关于Func和Action委托的介绍详解

目录
  • 1.Action委托
  • 2.Func委托

委托:委托(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 委托内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c# 委托和事件实例学习

    Common.cs: 复制代码 代码如下: using System; using System.Collections.Generic; using System.Text; namespace DelegateAndEvent.App_Code { public class Common { //定义全局变量. public static string txt = ""; #region 定义方法 public string HelloCSharp(string name) { t

  • c#委托与事件(详解)

    引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在.本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论. 将方法作为方法的参数 我们先不管这个标题

  • C#通过委托调用Button单击事件的方法

    这里介绍通过委托取消Button事件switch-case的方法.需要注意的是,事先要按顺序在各个Button的Tag属性中设置0.1.2.3--等序号,其作用请详看代码. /*定义委托*/ public delegate 类型或viod MethodDelegate(参数1, 参数2); private void buttonC_Click(object sender, EventArgs e) { Button button = (Button)sender; /*向委托添加方法*/ Met

  • C#零基础学习理解委托

    说来惭愧,在大学的课程中,竟然没有听说过委托这个名称.那么今天我就带着大家一起探讨下委托和事件. 咱们先来看下委托 我主要从以下几个方面讲解 1,  为什么使用委托  2.什么是委托  3.委托如何使用 为什么使用委托? 委托是c#中非常重要的一个概念,使用委托使程序员可以将方法引用封装在委托对象内.然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法.与C或C++中的函数指针不同,委托是面向对象,而且是类型安全的. 什么是委托? 委托是一种引用方法的类型,一旦为委

  • C#中委托的+=和-=深入研究

    写在前面 为什么会突然想说说委托?原因吗,起于一个同事的想法,昨天下班的路上一直在想这个问题,如果给委托注册多个方法,会不会都执行呢?为了一探究性,就弄了个demo研究下. += 大家都知道委托都继承自System.MulticastDelegate,而System.MulticastDelegate又继承自System.Delegate,可以通过+=为委托注册多个方法.那么他们是否都执行了呢?执行的结果又是怎样的呢?有返回值和没返回值的是否结果是否一样?那就试着说说+=都干了哪些事? 测试代码

  • 深入理解C#中常见的委托

    一提到委托,浮现在我们脑海中的大概是听的最多的就是类似C++的函数指针吧,呵呵,至少我的第一个反应是这样的.关于委托的定义和使用,已经有诸多的人讲解过,并且讲解细致入微.我就不用多废话了.今天我要说的是C#中的三种委托方式:Func委托,Action委托,Predicate委托以及这三种委托的常见使用场景.Func,Action,Predicate全面解析首先来说明Func委托,通过MSDN我们可以了解到,Func委托有如下的5种类型: 复制代码 代码如下: (1) *delegate TRes

  • C#中常见的系统内置委托用法详解

    一般来说,C#在公共语言运行时(CLR)环境中系统为我们内置了一些常用的委托,包括Action类的委托.Func类的委托.Predicate<T>委托.Comparison<T>委托等等.以上这些委托的命名空间都是System,所属程序集都是 mscorlib.dll,今天本文就来讲一讲这些委托的使用方法. 就像我们自己已定义好的一样,要实现某些功能,我们可以直接利用系统内置委托,实例化它们,而不必显式定义一个新委托并将命名方法分配给该委托.如: public static voi

  • C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);    public class 加法类    {        public static int Add(int a, int b)        {            Console.WriteLine("开始计算:" + a + "+" + b);            Thread.Sl

  • C#关于Func和Action委托的介绍详解

    目录 1.Action委托 2.Func委托 委托:委托(Delegate) 是存有对某个方法的引用的一种引用类型变量.引用可在运行时被改变. 委托(Delegate)特别用于实现事件和回调方法.所有的委托(Delegate)都派生自 System.Delegate 类. 1.Action委托 没有返回值,可以不包含参数 (1)声明委托.定位委托事件.向委托添加事件.执行委托 /// <summary> /// 不包含参数 /// </summary> private event

  • Python Django给admin添加Action的方法实例详解

    在使用Django自带的admin后台的时候,他提供了一些默认的指令可以对数据进行操作, 比如批量删除,修改等 同样的我们也可以添加自己的指令. 创建一个Django项目 $ django-admin startproject DjangoActions $ cd DjangoActions $ python3 manage.py startapp mysite添加model 打开mysite下的models.py from django.db import models class Artic

  • C#中List用法介绍详解

    目录 一.#List泛型集合 为什么要用泛型集合? a.使用ArrayList b.使用自定义集合类 什么是泛型? 怎样创建泛型集合? 泛型集合的排序 泛型集合的搜索 泛型集合的扩展 二.List的方法和属性 方法或属性 作用 三.List的用法 1.List的基础.常用方法: (1).声明: (2).添加元素: (3).删除元素: (5).给List里面元素排序: (6).给List里面元素顺序反转: (7).List清空: (8).获得List中元素数目: 2.List的进阶.强大方法: (

  • Unity中协程IEnumerator的使用方法介绍详解

    在Unity中,一般的方法都是顺序执行的,一般的方法也都是在一帧中执行完毕的,当我们所写的方法需要耗费一定时间时,便会出现帧率下降,画面卡顿的现象.当我们调用一个方法想要让一个物体缓慢消失时,除了在Update中执行相关操作外,Unity还提供了更加便利的方法,这便是协程. 在通常情况下,如果我们想要让一个物体逐渐消失,我们希望方法可以一次调用便可在程序后续执行中实现我们想要的效果. 我们希望代码可以写成如下所示: void Fade() { for (float f = 1f; f >= 0;

  • JavaScript中事件委托的示例详解

    目录 事件流 事件委托 结尾 大家好,我是前端西瓜哥.今天我们来认识一下事件委托. 所谓事件委托,就是将原本应该在当前元素绑定的事件,放到它的祖先元素上,让祖先元素来委托处理. 事件流 事件流指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序. 事件流由两阶段组成: 捕获事件 冒泡事件 我们通常用 addEventListener 给元素添加事件: document.querySelector('#card')addEventListener( 'click', function (ev

  • React状态管理Redux的使用介绍详解

    目录 1. 简介 2. 核心概念 3. redux工作流 4. 模拟redux工作流程 5. 使用redux 6. react-redux 1. 简介 Redux 是 JavaScript 应用的状态容器(对象),提供可预测的状态管理.可以让你开发出行为稳定可预测的应用,运行于不同的环境(客户端.服务器.原生应用),并且易于测试.Redux 除了和 React 一起用外,还支持其它界面库. 解决的问题:多层级组件间通信问题. 2. 核心概念 单一数据源 整个redux中的数据都是集中管理,存储于

  • Python图像处理库PIL的ImageGrab模块介绍详解

    ImageGrab模块用于将当前屏幕的内容或者剪贴板上的内容拷贝到PIL图像内存. 当前版本只支持windows系统. 一.ImageGrab模块的函数 1.  Grab 定义:ImageGrab.grab()⇒ image ImageGrab.grab(bbox) ⇒ image 含义:(New in 1.1.3)抓取当前屏幕的快照,返回一个模式为"RGB"的图像.参数边界框用于限制只拷贝当前屏幕的一部分区域. 例子: >>> from PIL importImag

  • Python图像处理库PIL的ImageDraw模块介绍详解

    ImageDraw模块提供了图像对象的简单2D绘制.用户可以使用这个模块创建新的图像,注释或润饰已存在图像,为web应用实时产生各种图形. PIL中一个更高级绘图库见The aggdraw Module 一.ImageDraw模块的概念 1.  Coordinates 绘图接口使用和PIL一样的坐标系统,即(0,0)为左上角. 2.  Colours 为了指定颜色,用户可以使用数字或者元组,对应用户使用函数Image.new或者Image.putpixel.对于模式为"1","

  • webpack5 联邦模块介绍详解

    本文主要介绍webpack 5 的新特性之一 "module federation"(联邦模块),涉及联邦模块特性.使用方法.适用范围. 特性 webpack 5引入联邦模式是为了 更好的共享代码 . 在此之前,我们共享代码一般用npm发包来解决. npm发包需要经历构建,发布,引用三阶段,而联邦模块可以 直接引用其他应用代码 ,实现热插拔效果.对比npm的方式更加简洁.快速.方便. 使用方法 引入远程js webpack配置 模块使用 引入远程JS 假设我们有app1,app2两个应

  • python安装及变量名介绍详解

    python基础部分学习 一,python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写能够解释Python语言语法的解释器.Python这个名字,来自Guido所挚爱的电视剧Monty Python's Flying Circus.他希望这个新的叫做Python的语言,能符合他的理想:创造一种C和shell之间,功能全面,易学易用,可拓展的语言. Python可以应用于众多领域,如:数据分析.组件集成.网络服务.图像处理

随机推荐