首页 > 编程语言 >C# Action 和 Func 区别

C# Action 和 Func 区别

时间:2023-12-25 16:46:35浏览次数:30  
标签:string 委托 C# int static Func Action public

C# Action 和 Func 区别

 

前言:

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

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

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

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

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

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

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

一:委托的申明

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

       eg: public delegate int MethodDelegate(int x,int y);    //两个参数,返回int类型

  2. Action  ,至少0个参数,无返回值的泛型委托

    Action<int,string,bool> ,有传入int、string、bool类型的参数,无返回值的委托

    eg: public void Test<Test>(Action<T> action,T p) {   actoin(p);   }

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

    Func<object,string,int> ,传入参数为object、string类型的参数,返回值为int的委托

    eg: public int Test<T1, T2>(Func<T1, T2, int>func,T1 a,T2 b){    return func(a, b);    }

  4.Predicate  ,有且只有一个参数,返回值只为 bool 类型

    predicate<int> 表示传入为int类型的参数,返回bool类型的委托。

    eg: public delegate bool Predicate<T>(T obj)

二:委托的使用

  1. delegate 

复制代码
    public delegate int MethodDelegate(int x,int y);
    private static MethodDelegate method;
    static void Main(string[]  args)
    {
      method = new MethodDelegate(Add);
      method(10,20);  
    }
       private static int Add(int x, int y)
    {
      return x +y;
    }
复制代码

  2. Action 

复制代码
    static void Main(string[] args)
    {
      Test<string>(Action, "Hello World");
      Test<string>(p => { Console.WriteLine("{0}", p); }, "Hello World" );
    }
    public static void Action(string s)
    {
      Console.WriteLine(s);
    }
    public static void Test<T>(Action<T> action,T p)
    {
      action(p);  
    }
复制代码

  3. Func的使用

复制代码
    static void Main(string[] args)
    {
      Test<int, int>(Fun, 100, 200);
    }
    public static int Test <T1, T2>(Func<T1, T2, int>func, T1 a,T2 b)
    {
      return func(a ,b);
    }
    private static int Fun(int a ,int b)
    {
      return a + b;
    }
复制代码

  4. predicate 的使用

复制代码
   static void Main(string[] args)
   {
      Point[] points = {
        new Point(100,200) ,
        new Point(250,375),
        new Point(150,250),
        new Point(275,395),
        new Point(295,450)
      };
      Point first = Array.Find(points,ProductGT10) ;
      Console.WriteLine("Found: X = {0},Y = {1}", frist.x, frist.Y);
   }
   private static bool ProductGT10(Point p)
   {
      if(p.X * p.Y > 100000)
      {
        return true;
      }
      else
      {
        return false;
      }
   }
复制代码

三:委托的清空

  1.在类中循环去除委托引用

复制代码
    public MethodDelegate OnDelegate;
   public void ClearDelegate()
   {
      while(this.OnDelegate != null)
      {
        this.OnDelegate -= this.OnDelegate;
      }
   }
复制代码

  2.在方法中查询出委托后去除

复制代码
  public MethodDelegate OnDelegate;
  static void  Main(string[] args)
  {
    Program test = new Program();
    if(test.OnDelegate != null)
    {
       System.Delegate[] dels = test.OnDelegate.GetInvocationList();
       for(int 1 = 0; i < dels.Length; i++)
        {
         test.OnDelegate -= dels[i] as MethodDelegate;
       }
    }
  }
复制代码

 PS:下面三种方式属于老式委托的使用,就不要用了。C#3.5之后都用  Action Func

 WithParaNoReturnEventHandler _WithParaNoReturnEventHandler = 
        new WithParaNoReturnEventHandler(MyDelegate.SayChinese); MyDelegate.Say("张三",_WithParaNoReturnEventHandler);  //C#1.0 传统调用 MyDelegate.Say("张三", delegate(string name) { Console.WriteLine("你好," + name); }); //C#2.0 匿名方法 MyDelegate.Say("张三", (name) => { Console.WriteLine("你好," + name); }); //C#3.0 lambda表达式

 

  

标签:string,委托,C#,int,static,Func,Action,public
From: https://www.cnblogs.com/sexintercourse/p/17926382.html

相关文章

  • C#版本与.NET版本对应关系以及各版本的特性
    C#版本与.NET版本对应关系以及各版本的特性 C#版本.NET版本发布日期特性C#1.0.NETFramework1.02002-02-13委托、事件C#1.1.NETFramework1.12003-04-24APM(异步编程模型)C#2.0.NETFramework2.02005-11-07泛型、匿名方法、迭代器、可空类型C#......
  • 在CentOS Linux系统上安装Docker
    安装Docker在CentOSLinux系统上的步骤如下:更新系统软件包列表:sudoyumupdate安装所需的软件包以支持Docker:sudoyuminstall-yyum-utilsdevice-mapper-persistent-datalvm2添加Docker的官方GPG密钥:sudoyum-config-manager--add-repohttps://download.docke......
  • C# 线程、线程池、Task概念+代码实践 C# 线程、线程池、Task概念+代码实践
    C#线程、线程池、Task概念+代码实践dotnet编程大全专注C#wpf开发,dotnet编程大全 1人赞同了该文章转自:JerryMouseLihttp://cnblogs.com/JerryMouseLi/p/14135600.html前言 线程中的概念很多,如果没有代码示例来理解,会比较晦涩,而且有些概......
  • 20、布局(QStackedWidget)
    QStackedWidget是Qt框架中的一个容器类,它可以用来管理多个窗口或页面,只显示其中一个窗口或页面。在QStackedWidget中,只有当前激活的窗口或页面可见,其他窗口或页面被隐藏。使用QStackedWidget可以方便地实现页面切换效果,比如制作一个具有多个页面的向导,或者实现一个选项卡......
  • C# Task详解
    C#Task详解 推荐几篇写的很好的文章,本文部分转自https://blog.csdn.net/btfireknight/article/details/97766193https://blog.csdn.net/boonya/article/details/80541571https://blog.csdn.net/nacl025/article/details/9163495/1.Task原理这里简要的分析下CLR线程池......
  • pthread_create用法,创建线程输出2*n
    #include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<unistd.h>void*calculate(void*arg){intvalue=*(int*)arg;longvalue_2=2*(long)value;printf("Thethread_idis%lu,createdby%d\n&qu......
  • Python - pandas 报错:ValueError: 'HIS_批准文号' is both an index level and a colu
    问题描述file:[Terminal]ValueError:'HIS_批准文号'isbothanindexlevelandacolumnlabel,whichisambiguous.ValueError:cannotinsert招采_批准文号,alreadyexists有这两个错误,使用函数merge合并的时候出现第一个错误,将两个DataFrame的索引reset_index......
  • EasyCVR视频监控系统/智能监控方案平台如何添加fmp4播放流协议?
    视频监控/GB28181视频管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,视频安防监控汇聚平台EasyCVR可支持1、4、9、16个画面窗口播放,可同时播放多路视频流,也能支持视频定时轮播。视频监控汇聚平台EasyCVR支持多种播放协议,......
  • [Mac软件]PullTube 1.8.5.22视频下载工具
    应用介绍黑果魏叔:使用PullTube,您可以下载YouTube或Vimeo上托管的所有在线视频或音频,包括整个播放列表。您可以选择保留原始格式或仅提取音频。通过YouTube或Vimeo等互联网托管服务共享视频是一种常见做法,但如果您的互联网连接速度较慢,流媒体内容可能无法正常工作。为了解......
  • a-date-picker设置禁用以前的时间(含时分秒)
     <a-date-pickerv-model="selectTime"show-timeformat="YYYY/MM/DDHH:mm:ss"valueFormat="YYYY-MM-DDHH:mm:ss":disabled-date="disabledDate":disabled-time="disabledTime"placeholder......