委托

2021-08-09  本文已影响0人  扶不起的蝌蚪

简介

C#的委托与JS中的回调函数非常相似,即先定义一个形参为委托,而这个形参委托存储的是其实例化所绑定的方法,那么委托执行的时候,实际上是其绑定的方法在执行,用户只需要在委托绑定的方法中编写自己的业务逻辑而不必关心在委托是如何具体调用的。

委托的使用会经历如下的过程

1.委托的声明

定义委托,即告知编译器这个委托可以指向那些类型的方法
语法:<访问修饰符> delegate 返回类型 委托名称(形参类型1 形参名1,...形参类型N 形参名N)

public delegate void DelagateName(int intParam, string strParam)

2.委托的实例化

需要进行委托声明

  • 委托名 委托变量 = new 委托名(目标类名.静态方法名)
  • 委托名 委托变量 = 目标类名.静态方法名
  • 委托名 委托变量 = new 委托名(new 目标类().方法名)
  • 委托名 委托变量 = new 目标类().方法名
  • 委托名 委托变量 = delegate(参数){会调用的方法体} //匿名方法
  • 委托名 委托变量 = ((参数1,...参数n)=>{会调用的方法体}) //Lambda

不需要进行委托声明(语法糖自动帮我们进行声明)

  • Action<参数1,... 参数N> 委托名= new Action(目标类名.静态方法名)
  • Action<参数1,... 参数N> 委托名= 目标类名.静态方法名
  • Action<参数1,... 参数N> 委托名= new Action(new 目标类().方法名)
  • Action<参数1,... 参数N> 委托名= new 目标类().方法名
  • Action<参数1,... 参数N> 委托名= delegate(参数){会调用的方法体}
  • Action<参数1,... 参数N> 委托名= ((参数1,... 参数N) => {不带返回值的方法体 })
  • Func<参数1,... 参数N> 委托名= new Func(目标类名.静态方法名)
  • Func<参数1,... 参数N> 委托名= 目标类名.静态方法名
  • Func<参数1,... 参数N> 委托名= new Func(new 目标类().方法名)
  • Func<参数1,... 参数N> 委托名= new 目标类().方法名
  • Func<参数1,... 参数N> 委托名= delegate(参数){会调用的方法体}
  • Func<参数1,... 参数N,返回值> 委托名= ((参数1,... 参数N) => {带返回值的方法体 })
public delegate int Call(int num1, int num2);
class SimpleMath
{
    // 乘法方法
    public static int Multiply(int num1, int num2)
    {
        return num1 * num2;
    }

    // 除法方法
    public int Divide(int num1, int num2)
    {
        return num1 / num2;
    }
}


class Test
{
    static void Main(string[] args)
    {
        //委托名 委托变量 = new 委托名(目标类名.静态方法名)
        Call objCall = new Call(SimpleMath.Multiply);
        //委托名 委托变量 = 目标类名.静态方法名
        Call objCall = SimpleMath.Multiply;
        //new 委托名(new 目标类().方法名)
        Call objCall1 = new Call(new SimpleMath().Divide);
        //委托名 委托变量 = new 目标类().方法名
        Call objCall1 = new SimpleMath().Divide;
        //委托名 委托变量 =  delegate(参数){会调用的方法体} 
        Call objCall = delegate(int a, int b)
        {
            return a * b;
        };
        Call objCall1 = delegate(int a, int b)
        {
            return a / b;
        };
        //委托名 委托变量 = ((参数1,...参数n)=>{会调用的方法体})
        Call objCall =((int a,int b)=> { return a*b;});
        //委托名 委托变量 = ((参数1,...参数n)=>{会调用的方法体})
        Call objCall1 = ((int a, int b) => { return a / b; });
        //如果是委托泛型方式声明的
        //就把顶部的public delegate int Call(int num1, int num2)去掉
        Func<int, int, int> objCall = ((a, b) => { return a * b; });
        Func<int, int, int> objCall1 = ((a, b) => { return a / b; });
        Action<int, int> ob = ((a, b) => { Console.WriteLine(a * b); });
        //ob(5, 3);
        //----------------------------------------------------//
        //int result = objCall(5, 3);
        //int result1 = objCall1(5, 3);
        //System.Console.WriteLine("结果1为 {0},结果2为{1}", result,result1);
        //Console.ReadKey();
    }
}

3.委托作为参数进行传递(回调函数)

声明委托
namespace ConsoleApp1
{
    public delegate int Call(int num1, int num2);
    class Program
    {
        static void Main(string[] args)
        {
            //委托实例化后传入
            Call call = SimpleMath.Multiply;
            int num0 = startTest(2, 3, call);
            //直接传入静态方法,语法糖内部自动进行实例化
            int num1 = startTest(2, 3, SimpleMath.Multiply);
            //直接传入方法,语法糖内部自动进行实例化
            int num2 = startTest(2, 3,new SimpleMath().Divide);
            //报错因为add方法与声明的public delegate int Call(int num1, int num2)参数不匹配
            int num3 = startTest(2, 3, SimpleMath.add);
            //系统会问我们是否生成对应的修补程序
            // private static int startTest(int v1, int v2, Func<int, int, int, int> add)
            // {
            //throw new NotImplementedException();
            // }

            Console.ReadKey();
        }
        public static int startTest(int a, int b, Call call)
        {
            return call(a, b);
        }
    }
    class SimpleMath
    {
        // 乘法方法
        public static int Multiply(int num1, int num2)
        {
            Console.WriteLine("执行乘法");
            return num1 * num2;
        }

        // 除法方法
        public int Divide(int num1, int num2)
        {
            Console.WriteLine("执行除法");

            return num1 / num2;
        }

        // 加方法
        public static int add(int num1, int num2, int num3)
        {
            Console.WriteLine("执行加法");
            return num1 + num2 + num3;
        }
    }

}
不声明委托
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int num1 = startTest(2, 3, SimpleMath.Multiply);

            Console.ReadKey();
        }

        private static int startTest(int v1, int v2, Func<int, int, int> fun)
        {
           return fun(v1, v2);
        }
    }
    class SimpleMath
    {
        // 乘法方法
        public static int Multiply(int num1, int num2)
        {
            Console.WriteLine("执行乘法");
            return num1 * num2;
        }

        // 除法方法
        public int Divide(int num1, int num2)
        {
            Console.WriteLine("执行除法");

            return num1 / num2;
        }

        // 加方法
        public static int add(int num1, int num2, int num3)
        {
            Console.WriteLine("执行加法");
            return num1 + num2 + num3;
        }
    }
}
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int num1 = startTest(2, 3, (x,y)=> x*y);
            Console.WriteLine(num1);
            Console.ReadKey();
        }

        private static int startTest(int v1, int v2, Func<int, int, int> fun)
        {
           return fun(v1, v2);
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读