c#-委托(delegate)

什么是委托

委托是函数指针升级版。C#使用委托来完成C/C++语言中的函数指针功能,相对于函数指针,委托能够完成更多的功能。
如果你熟悉Java的话,会发现Java既没有委托,也没有函数指针。在Java中,Java使用接口来完成这一操作,特别是Java8之后的函数式接口,意图更明显。
使用委托可以间接调用方法。


委托滥用会造成灾难,因此在C#中可以学学Java使用接口来完成部分委托的功能。

使用系统预定义的委托

Action

Action是没有返回值和参数列表为空的方法的委托。

class Pragram
    {
    
    
        static void Main(string[] args)
        {
    
    
            Calc calc = new Calc();
            Action action = new Action(calc.PrintInfo);
            // 委托调用
            action.Invoke();
            action(); // 简洁写法
        }
    }

    class Calc
    {
    
    
        public void PrintInfo()
        {
    
    
            Console.WriteLine("class Calc.");
        }
    }

Func

Func共有17中泛型,分别用来对应不同参数列表个数的方法。
Func<out TResult> 对应的方法结构为: TResult Method(){...}, TResult是返回值类型的泛型
Func<in T, out TResult>TResult Method(T a){...}
Func<in T1, in T2, out TResult>TResult Method(T1 a, T2 b){...}

class Pragram
    {
    
    
        static void Main(string[] args)
        {
    
    
            Calc calc = new Calc();
            Func<int, int, int> func1 = new Func<int, int, int>(calc.Add);
            Func<int, int, int> func2 = new Func<int, int, int>(calc.Sub);

            int a = 100;
            int b = 200;
            int res;

            res = func1(a, b); // 调用calc.Add方法
            Console.WriteLine(res); // 输出300
            res = func2(a, b); // 调用calc.Sub方法
            Console.WriteLine(res); // 输出-100
        }
    }

    class Calc
    {
    
    
        public int Add(int a, int b)
        {
    
    
            return a + b;
        }

        public int Sub(int a, int b)
        {
    
    
            return a - b;
        }
    }

自定义委托

委托的声明

委托是一种类(class),类是数据类型,所以委托也是一种数据类型。
声明的一般格式如下:
访问修饰符 delegate 返回值类型 委托名称(参数列表);

// 声明委托
public delegate void SayHi(string name);

class Pragram
{
    
    
	static void Main(string[] args)
	{
    
    
	    SayHi sayHi = new SayHi(Hi);

		sayHi.Invoke("张三");
	}

	static void Hi(string name)
	{
    
    
		Console.WriteLine("Hi, {0}", name);
	}
}

使用委托

一般使用委托的正确方式有回调函数(什么是回调函数)和模板方法(什么是模板方法)。

多播委托

public delegate void SayHi(string name);
class Pragram
{
    
    
    static void Main(string[] args)
    {
    
    
        SayHi sayHi1 = new SayHi(Hi1);
        SayHi sayHi2 = new SayHi(Hi2);
        SayHi sayHi3 = new SayHi(Hi3);

        sayHi1 += sayHi2;
        sayHi1 += sayHi3;

        sayHi1.Invoke("张三"); // sayHi2和sayHi3同样会被调用
    }

    static void Hi1(string name)
    {
    
    
        Console.WriteLine("Hi1, {0}", name);
    }

    static void Hi2(string name)
    {
    
    
        Console.WriteLine("Hi2, {0}", name);
    }

    static void Hi3(string name)
    {
    
    
        Console.WriteLine("Hi3, {0}", name);
    }
}

隐式异步调用

使用委托的BeginInvoke方法可以进行隐式异步调用。

public delegate void SayHi(string name);
class Pragram
{
    
    
    static void Main(string[] args)
    {
    
    
        SayHi sayHi1 = new SayHi(Hi1);
        SayHi sayHi2 = new SayHi(Hi2);
        SayHi sayHi3 = new SayHi(Hi3);

        sayHi1.BeginInvoke("张三", null, null);
        sayHi2.BeginInvoke("李四", null, null);
        sayHi3.BeginInvoke("王五", null, null);
    }

    static void Hi1(string name)
    {
    
    
        Console.WriteLine("Hi1, {0}", name);
    }

    static void Hi2(string name)
    {
    
    
        Console.WriteLine("Hi2, {0}", name);
    }

    static void Hi3(string name)
    {
    
    
        Console.WriteLine("Hi3, {0}", name);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45345384/article/details/128482117