• 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();
            }
        }
    }
    
  • 相关阅读:
    前端试题-正则中test, exec, match的区别
    前端试题-什么是css sprite?优缺点?
    有哪些软件堪称「神器」,却不被大众所知?(转)
    gif,png,jpg的区别
    前端试题-两列等高布局
    20160109小问题
    动画效果之运动
    用JS控制下拉菜单效果
    获取当前时间getDate()注意点
    全心加入web前端开发,向上吧!
  • 原文地址:https://www.cnblogs.com/AlinaL/p/12852175.html
Copyright © 2020-2023  润新知