C#学习笔记之——委托(delegate)

菜鸟教程-委托

当遇到在运行时才能决定用哪种方法的时候,使用委托。

可以把delegate看做一个包含有序方法列表的对象,这些方法具有相同的签名和返回类型。

定义一个委托

<访问修饰符> delegate <返回类型> <委托名> (<参数列表>)

访问修饰符不是必须的

public delegate int MyDelegate (int s);

委托的例子

using System;

namespace 委托
{
    delegate void MyDel(int value);//声明委托类型

    class MainClass
    {
        public static void Main(string[] args)
        {
            MainClass mainClass = new MainClass();
            MyDel del;//声明

            //随机产生一个0-99之间的随机数
            Random random = new Random();
            int randomValue = random.Next(99);

            del = (randomValue < 50) 
                ? new MyDel(mainClass.PrintLow) 
                : new MyDel(mainClass.PrintHigh);//xxx ? xxx : xxx

            del(randomValue);//执行委托


        }

        void PrintLow(int value)
        {
            Console.WriteLine("{0} - Low Value", value);
        }

        void PrintHigh(int value)
        {
            Console.WriteLine("{0} - High Value", value);
        }
    }
}

委托也可以有泛型

可以这样实例化,委托对象必须使用 new 关键字来创建,声明变量并创建类型的对象。

public delegate void printString(string s);
。。。
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);

或这样

printString ps1;
ps1 = WriteToScreen;

还可以不取名字,不单独写函数,如果是只需要用一次的情况,这样可以更方便

printString = delegate (int a) {
  函数体
}

组合委托

MyDel delA = myInstObj.MyM1;
MyDel delB = SClass.otherM2;

MyDel delC = delA + delB;

代码创建了三个委托,第三个委托由前两个委托组合而成。 

多播

委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。
使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播。

public delegate void Greeting (string name);
public static void ChineseGreeting(string name)
{
	Console.WriteLine (name + "先生你好!");
}
public static void JapaneseGreeting(string name)
{
	Console.WriteLine ("{0}さん、こんにちは",name);
}
GreetingDelegate greet;
greet = ChineseGreeting;
greet += JapaneseGreeting;
greet ("李");

这样会输出

李先生你好!

李さん、こんにちは

当然用-=就会去掉,不过如果去掉本来没在greet里面的,比如写greet -= EnglishGreeting也不会报错

调用带返回值的委托

using System;

namespace 委托
{
    delegate int MyDel();//声明委托类型

    class MainClass
    {
        public static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            MyDel del = myClass.Add1;//创建并初始化
            del += myClass.Add2;//增加方法
            del += myClass.Add1;//增加方法

            Console.WriteLine("Value:{0}", del());

        }
    }

    class MyClass
    {
        int value = 5;
        public int Add1()
        {
            value += 2;
            return value;
        }
        public int Add2()
        {
            value += 3;
            return value;
        }
    }
}

//结果为12

Lambda表达式

下面的效果一样

using System;

namespace 委托
{
    delegate double MyDel(int par);//声明委托类型

    class MainClass
    {
        public static void Main(string[] args)
        {
            MyDel del = delegate(int x) {
                return x + 1;
            };
            MyDel del1 = (int x) =>
            {
                return x + 1;
            };
            MyDel del2 = (x) =>
            { 
                return x + 1; 
            };
            MyDel del3 = x =>
            {
                return x + 1;
            };
            MyDel del4 = x => x + 1;
        }
    }
}

Lambda表达式和委托的小例子

using System;

namespace ConsoleApp1
{

    class Example
    {
        public int Plus1(int a, int b)
        {
            return a + b;
        }

        public int Plus2(int a, int b) => a + b;

        public void Plus3(int a, int b) => Console.WriteLine(a + b);

        public delegate int DeleLambdaEmpty();
        public delegate int DeleLambdaOne(int a);
        public delegate int DeleLambdaTwo(int a, int b);


        static Func<string, string, string> GetFunc = (p1, p2) => { return p1 + " " + p2; };
        

        public static Func<int, int, bool> testForEquality = (x, y) => x == y;

        static void Main()
        {
            Example example = new Example();

            Console.Write("Plus1(1, 2):");
            Console.WriteLine(example.Plus1(1, 2));

            Console.Write("Plus2(1, 2):");
            Console.WriteLine(example.Plus2(1, 2));

            Console.Write("Plus3(1, 2):");
            example.Plus3(1, 2);

            DeleLambdaEmpty deleLambdaEmpty = () => { return 0; };
            Console.Write("DeleLambdaEmpty():");
            Console.WriteLine(deleLambdaEmpty());

            DeleLambdaOne deleLambdaOne = a => { return a; };
            Console.Write("DeleLambdaOne():");
            Console.WriteLine(deleLambdaOne(1));

            DeleLambdaTwo deleLambdaTwo = (a,b) => { return a + b; };
            Console.Write("DeleLambdaTwo():");
            Console.WriteLine(deleLambdaTwo(1,1));

            Console.Write("testForEquality(1,2):");
            Console.WriteLine(testForEquality(1, 2));

            var c = GetFunc(example.Plus1(1, 2).ToString(), example.Plus1(3, 4).ToString());
            Console.Write("GetFunc():");
            Console.WriteLine(c);

            Console.ReadKey();
        }
    }
}
原文地址:https://www.cnblogs.com/AlinaL/p/12852175.html