Action与Func委托

1. 委托 

     如果我们要把方法当作参数来传递的话,就需要用委托。简单说,委托是一个类型,这个类型可以复制一个方法的引用。

 

    声明委托: 

  delegate void method(int x, string y);   //注意是方法签名

     class Program
     {  private delegate string Getstring();  //定义委托
        static void Main(string[] args)
        {   int x = 40; 
            Getstring a = x.ToString; //a指向了x中的Tostring方法,没有调用方法,
                                    //注:Getstring a = new Getstring(x.ToString)这样也可以
            string s = a();   //通过委托去调用x中的tostring方法。
            Console.WriteLine(s);
            Console.ReadKey();
        }
   namespace ConsoleApplication1
   {  class program
       {
        delegate double Deloperate(double num1, double num2); //声明委托,名字随便

        static void Main(string[] args)
        {   Deloperate delop = new Deloperate(Add); //实例化委托 
            double results = delop(2.3, 5.6);       //委托调用方法,delop.Invoke(2.3,5.6)也可以
 
            Console.WriteLine(result);
            Console.ReadKey();
        }
        static double Add(double a, double b)
        {
            return a + b;
        }

  
  2. Action委托
 
    只能指向一个无返回值的方法。

 
    static void Print()
      {
          Console.WriteLine("Hello world");
      } 
    static void Print2(int i, int j)
        {
            Console.WriteLine(i+j);
        } 
     static void Main(string[] args)
      {
          Action a = Print;            // 或者 Action a = new Action(Print);
             a();

           Action<int, int> a = Print;    //参数类型要对应,还是没有返回值;Action<T>是Action的泛型实现
            a(12,34); 
   
      Console.ReadKey();  
     }


 3. 多播委托(委托链)

      static void Test1()
         {
            Console.WriteLine("test1");
          }
      static void Test2()
        {
            Console.WriteLine("test2");
        } 
       static void Main(string[] args)
        {
            Action a = Test1;
            a += Test2;            //多播委托就是同时指向多个方法,注意 
            a();

            Console.ReadKey();
        }


 4. Func委托


    static int Test1()
        {
          return 1;
        }
   static int Test2(string str)
        {
            Console.WriteLine(str);
            return 100;
        }
   static int Test3(int i, int j)
        {
            return i+j;
        }
        static void Main(string[] args)
        {
            Func<int> a = Test1;  //必须要有返回值
            Console.WriteLine(a());
 
            Func<string, int> b = Test2; //必须要对应
            Console.WriteLine(b("fuck"));
 
            Func<int, int, int> c = Test3;  //两个参数,一个返回值,一一对应
            Console.WriteLine(c(2, 3));

            Console.ReadKey();
        }



===============================================================================================

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用if-else(switch)语句,同时使得程序具有更好的可扩展性。

使用委托可以将多个方法绑定到同一个委托变量上(通常称这个委托变量为:委托链),当调用此变量时,会依次调用所有绑定的方法;于此同时,也可以通过类似绑定的方式删除方法。

using System;
using System.Collections;

namespace Delegate
{
    //用delegate关键字声明一个委托
    //委托原型必须与预委托的方法具有相同的返回值和参数类型
    delegate void MyDelegate(string name);

    public class Test
    {
     //要进行委托的方法
static void LearnA(string name) { Console.WriteLine("小王在学" + name); }        static void LearnB(string name) { Console.WriteLine("小张在学" + name); } static void Main() { //创建委托实例,并把委托函数名当作参数传递给委托对象 MyDelegate delegate1 = new LearnDelegate(LearnA); MyDelegate delegate2 = new LearnDelegate(LearnB); //通过委托对象,给绑定的函数传递参数,其实现在的learn_A和learn_B就是learnA和learnB的函数别名 delegate1("C#"); gelegate2("C++"); } } }



委托链

复制代码
static void Main()
{
  //创建委托实例
  LearnDelegate learn_A = new LearnDelegate(LearnA);
  LearnDelegate learn_B = new LearnDelegate(LearnB);

  //声明一个委托链,不需要实例化它
  LearnDelegate DelegateLst;
  //把委托对象直接相加并赋给委托链
  DelegateLst = learn_A + learn_B;
  //给委托链传值
  DelegateLst("编程");

  Console.WriteLine();

  //同样,也可以对委托链中的委托对象进行添加和删除操作

  DelegateLst -= learnA;//删除一个委托方法,这里使用DelegateLst -= Learn_A;效果是一样的,因为此时可以看作它是LearnA方法的一个别名
  DelegateLst("编程");
  Console.WriteLine();
            
  DelegateLst += learnB;//添加一个委托方法,同样这里也可以使用DelegateLst += Learn_B;
  DelegateLst("编程");
}
复制代码

 

委托链的简化使用

复制代码
using System;
using System.Collections;

namespace Delegate
{
    //用delegate关键字声明一个委托
    //委托原型必须与预委托的方法具有相同的返回值和参数类型
    delegate void LearnDelegate(string name);

    public class Test
    {
        static void Main()
        {
            //声明一个委托链,赋null值
            LearnDelegate DelegateLst = null;
            //下面这种形式其实是匿名方法的一种应用
            DelegateLst += delegate(string name) { Console.WriteLine("小王在学" + name); };
            DelegateLst += delegate(string name) { Console.WriteLine("小张在学" + name); };
            DelegateLst("编程");
        }
    }
}
复制代码

 

最后的一个例子

复制代码
using System;
using System.Collections;

namespace Delegate
{
    //用delegate关键字声明一个委托
    //委托原型必须与预委托的方法具有相同的返回值和参数类型
    delegate void AnimalDelegate(string AnimalName);
    class Animal
    {
        public Animal()
        {

        }

        //要进行委托的方法
        public void Miaow(string name)
        {
            Console.WriteLine( name + " 喵喵叫");
        }
        //要进行委托的方法
        public void Bark(string name)
        {
            Console.WriteLine(name + " 汪汪叫");
        }
        //要进行委托的方法
        public void Baa(string name)
        {
            Console.WriteLine(name + " 咩...");
        }
         
    }

    public class MainFunc
    {
        static void choseAnimal(string name, AnimalDelegate delegateFun)
        {
            delegateFun(name);
        }
        static void Main()
        {
            /*AnimalDelegate cat = new AnimalDelegate(new Animal().Miaow);
            cat("猫咪");
            AnimalDelegate dog = new AnimalDelegate(new Animal().Bark);
            dog("狗狗");*/
            
            //上下的两种调用方式是等价的

            choseAnimal("喵星人", new Animal().Miaow);
            choseAnimal("汪星人", new Animal().Bark);
            choseAnimal("喜洋洋", new Animal().Baa);
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

屠变恶龙之人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值