C# Action和Func的用法详解

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

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

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

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

   当我们窗体传值、线程启动时绑定方法、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和匿名方法处理方法体内逻辑。

posted @ 2023-05-11 18:38  以德为先  阅读(9193)  评论(0编辑  收藏  举报