首页 > 编程语言 >C# Action和Func的用法详解

C# Action和Func的用法详解

时间:2023-05-11 18:45:47浏览次数:30  
标签:string C# void int 参数 Func Action

委托是一个类,定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。

   把一个 参数类型 返回值 相同 方法名不同 的方法当变量 的方法 叫委托。

   为了实现程序的六大设计中的开闭原则:解耦,对修改关闭,对扩展开放。逻辑分离。

   直接调用函数和使用委托调用函数的区别就是是否方便对外扩展。

   当我们窗体传值、线程启动时绑定方法、lambda表达式、异步等等情况下需要用到。

事件是一种特殊的委托,本质就是委托,事件是回调机制的一种应用。

   当委托调用的函数达到某种条件时,可以通过回调通知调用者。

1. delegate 至少0个参数,至多32个参数,可以无返回值,可以指定返回值类型

private delegate int MethodDelegate(int x,int y); //两个参数,返回int类型
static void Main(string[]  args)
{
  MethodDelegate method = new MethodDelegate(Add);
  int result = method(10,20);  
}
private static int Add(int x, int y)
{
  return x +y;
}      

平时用委托的一般方式,先声明委托,然后再去使用,有点麻烦,.net中有已经定义好的委托类型Action 和 Func,可以拿来直接用。

2. Action  至少0个参数,至多16个参数,没有返回值的泛型委托

static void Main(string[] args)
{
    Action<string> BookAction = new Action<string>(Book); //一个参数
    BookAction("百年孤独");
}
public static void Book(string BookName)
{
    Console.WriteLine("我是买书的是:{0}",BookName);
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ActionDemo : MonoBehaviour
{
    Action  action;//表示无参
    Action<int> action1;//表示有传入参数int
    void Start()
    {
        action = actionH1;//没有参数
        action();

        action1 = actionH2;//一个 int参数 
        action1(456);

        actionH3(() => { Debug.Log("执行完actionH3了"); });//lambda 表达式 来执行委托

        actionH3(actionH4);//执行完 actionH3后回调 actionH4方法
    }

    private void actionH1()//没有参数
    {
        Debug.Log(123);
    }
    private void actionH2(int index)//参数int
    {
        Debug.Log(index);
    }
    private void actionH3(Action act)//参数 Action
    {
        Debug.Log("在执行actionH3");
        act();//回调 这个 委托方法
    }
    private void actionH4()//执行完 actionH3后的回调执行
    {
        Debug.Log("执行完actionH3了");
    }
}   

3. Func  至少0个参数,至多16个参数,必须有返回值的泛型委托

没有参数只有返回值的方法

static void Main(string[] args)
{
    Func<string> RetBook = new Func<string>(FuncBook); //无参的Func 返回一个string
    //Func<string> RetBook = FuncBook; //也可以直接这样
    Console.WriteLine(RetBook); //执行 这个委托
}
public static string FuncBook()
{
    return "送书来了";
}

有参数有返回值的方法

static void Main(string[] args)
{
    Func<string, string> RetBook = new Func<string, string>(FuncBook); //有一个参数的Func,返回一个string
    //Func<string,string> RetBook = FuncBook; //也可以直接这样
    Console.WriteLine(RetBook("aaa")); //执行 这个委托
}
public static string FuncBook(string BookName)
{
    return BookName;
}

Func一个很重要的用处就是传递值,下面举一个简单的代码来说明

Func<string> funcValue = delegate
{
    return "我是即将传递的值3";
};
DisPlayValue(funcValue);

注释1:DisplayVaue是处理传来的值,比喻缓存的处理,或者统一添加数据库等

private static void DisPlayValue(Func<string> func)
{
    string RetFunc = func();
    Console.WriteLine("我在测试一下传过来值:{0}",RetFunc);
}

完整示列如下:

 public class Person 
      { 
         public string Name { set; get; } 
         public int Age { set; get; } 
         public bool Gender { set; get; } 
         /// <summary> 
         /// 重写tostring方法,方便输出结果 
         /// </summary> 
         /// <returns></returns>
         public override string ToString()
         {
             return Name + "\t" + Age + "\t" + Gender;
         }
     }
     class Program
     {
         static void Main(string[] args)
         {
             Func<Person, Person> funcUpdateAge = new Func<Person, Person>(UpdateAge);
             Func<Person, Person> funcUpdateAge2 = UpdateAge; 
             Func<Person, Person> funcUpdateGender = (p1) => { p1.Gender = false; return p1; };//lambda表达式方式
             Func<Person, Person> funUpdateName = delegate(Person p2)//匿名方法
             {
                 p2.Name = "Wolfy2";
                 return p2;
             };
             Person p = new Person() { Name = "Wolfy", Age = 24, Gender = true };
             Person result = funcUpdateAge(p);
             Person result2 = funcUpdateAge2(p);
             Console.WriteLine(result.ToString());
             Console.WriteLine(result2.ToString());
             Console.WriteLine(funcUpdateGender(p).ToString());
             Console.WriteLine(funUpdateName(p).ToString());
             Console.Read();
         }
         static Person UpdateAge(Person p)
         {
             p.Age = 25;
             return p;
         }
     }
View Code

记住无返回值就用Action,有返回值就用Func

Action:无参数无返回值委托。

Action<T>:泛型委托,无返回值,根据输入参数的个数不同有十六个重载。

Func<out T>:无输入参数,有返回值。

Func<in T,out T>:有输入参数,有返回值,根据输入参数个数不同,有十六个重载。

Action和Func中可以使用Lambda和匿名方法处理方法体内逻辑。

标签:string,C#,void,int,参数,Func,Action
From: https://www.cnblogs.com/li150dan/p/17391919.html

相关文章

  • cuda nbody实验
    1并行化非常简单得,直接分配4096线程处理,每个线程处理一个天体。每个kernel函数中的循环,就去全局变量里面找其他点的信息,进行计算就好了2优化2.1共享内存按1中的,是每个线程处理n个,这里的话,每个线程分批次处理,每次处理一部分。引入共享内存。......
  • ChatGPT 再遭禁用 | 人工智能时代下数据安全如何保障
    近日,三星电子宣布禁止员工使用流行的生成式AI工具,原因在于4月初三星内部发生的三起涉及ChatGPT误用造成的数据泄露事件。报道称,三星半导体设备测量资料、产品良率等内容或已被存入ChatGPT学习资料库中。去年11月上线以来,ChatGPT一直是科技领域的焦点。上线短短5天,注册用户数......
  • 几个echarts使用小案例
    1y轴名称放左边、辅助线、时间轴标签、数值轴间隔<divid="main"style="height:400px"></div><script>varchartDom=document.getElementById("main");varmyChart=echarts.init(chartDom);varoption;option={xAxis......
  • [每天例题]蓝桥杯 C语言 密码发生器
    密码发生器题目 思路分析1.声明一个字符型二维数组,将输入的名字储存到数组里面2.定义一个整形数组存储密码3.将所有垂直在同一个位置的字符的ascii码值相加4.进行缩位处理 代码#include<stdio.h>intsuowei(intsum){inta,b;while(sum>=10){......
  • Vue3 + Vite4.3 + Element-Plus + TypeScript 从0到1搭建企业级后台管理系统(前后端开
    vue3-element-admin是基于vue-element-admin升级的Vue3+ElementPlus版本的后台管理前端解决方案,技术栈为Vue3+Vite4+TypeScript+ElementPlus+Pinia+VueRouter等当前主流框架。相较于其他管理前端框架,vue3-element-admin的优势在于一有一无有配套后端、无......
  • web游览器的标签页仿 ios mac 苹果的墓碑机制 (js代码)
    背景:本来项目开发系统防挂机功能,在其余游览器中均可以使用。但是呢在苹果的safair游览器中会出现几率失效,最后经过排查发现是苹果的墓碑机制导致。即:此标签页活跃,其他标签页假死。然后就导致防挂机失效了。原理:假如当前游览器中有3个标签页分别是A,B,C,每个标签页都有倒计时。正......
  • SEDCN:Structure enhanced deep clustering network via a weighted neighbourhood a
    论文阅读08-SEDCN:Structureenhanceddeepclusteringnetworkviaaweightedneighbourhoodauto-encoder论文信息论文地址:Structureenhanceddeepclusteringnetworkviaaweightedneighbourhoodauto-encoder-ScienceDirect代码地址:m22453/sedcn-nn(github.com)1.......
  • questions_03 【http://127.0.0.1:8000/%5Emanage/(%3FP1%5Cd+)/dashboard/】项目id参
    【原因背景】当我们在点击进入具体项目的时候,根据我们所写的url,中间应该包含我们的项目id,当不知道什么原因可以进入项目,但是id是乱码的【原因分析】在查看相关资料后发现是我们在写path的时候出现的问题:Django2.2.x之后的版本path:用于普通路径,不需要自己手动添加正则首位......
  • Java8中的sort与Comparator、Comparable
    基本含义在Java8中,sort()方法、Comparator接口和Comparable接口是用于对数组或集合进行排序的重要工具,其中Comparator接口适用于自定义比较规则,而Comparable接口适用于定义对象自身的比较规则。假如我们有一个实体类点击查看代码publicclassCoinUserIncome{pr......
  • [每天例题]蓝桥杯 C语言 连续奇数和
    连续奇数和题目 思路分析1.采用双for,第一个for用于记录起始数字,第二个for计算和2.如果sum==111的立方,则输出起始数字,如果大于,则跳转到第一个for增大起始数字代码#include<stdio.h>intmain(){ longlongintn; n=111*111*111; inti,j; intsum=0; for(i=1;i<100......