浅谈C#委托的用法-delegate

一、委托的概念

  1. 委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行。

  2. 借用百度上的一句话概括:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,

    可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性

二、委托的声明

  与对应的方法具有相同的参数类型、参数个数、返回值。通俗来讲就是“函数的模板原型”。

三、委托的使用

  1. 用delegate声明一个委托
  2. 委托实例化
  3. 调用
      public class DelegateClass
         {
            public delegate void DelegateTest(int a, int b);  //1、声明一个委托
     
           public static void Test()
            {
                 DelegateTest method = new DelegateTest(Plus);   //2、实例化委托
                 //DelegateTest method1 = Plus;  //实例化委托的另一种等价写法
                 method.Invoke(1, 2);   //3、调用
                //method1(3, 4);   //调用的另一种等价写法
             }
     
             private static void Plus(int a, int b)
           {
                 Console.WriteLine("a={0} b={1}", a, b);
             }
         }
    

      

    四、委托的意义

      1、没有委托就没有异步

      2、解耦

      3、高效扩展

    public class CallStudent
        {
            //方法1
            public static void CallStudentA(string name)
            {
                Console.WriteLine("{0}", name);
            }
            //方法2
            public static void CallStudentB(string name)
            {
                Console.WriteLine("{0}", name);
            }
            //方法3
            public static void CallStudentC(string name)
            {
                Console.WriteLine("{0}", name);
            }
    
            //传值的方式,根据值来决定行为,所有的方法全部耦合在一起,
            //如果要增加方法则需要修改该方法,不便于方法的封装、扩展
            public static void CallStudentName(string name, StudentType type)
            {
                if (type == StudentType.A)
                {
                    Console.WriteLine("{0}", name);
                }
                else if (type == StudentType.B)
                {
                    Console.WriteLine("{0}", name);
                }
                else if (type == StudentType.C)
                {
                    Console.WriteLine("{0}", name);
                }
            }
    
            //用委托的方式来实现传递方法,如果要增加方法,只需要重新增加一个方法就好
            public static void CallStudentName(string name, CallStudentHandler handler)
            {
                handler.Invoke(name);
            }
        }
    
        public delegate void CallStudentHandler(string name);
    
        public enum StudentType
        {
            A,
            B,
            C
        }
    

      

    static void Main(string[] args)
            {
                //用不同的值来区分不同的方法
                CallStudent.CallStudentName("Student A",StudentType.A );
                CallStudent.CallStudentName("Student B", StudentType.B);
                CallStudent.CallStudentName("Student C", StudentType.C );
                Console.WriteLine();
    
                //用委托的方式传递多个方法
                CallStudentHandler handlerA = new CallStudentHandler(CallStudent.CallStudentA);
                CallStudent.CallStudentName("Student A", handlerA);
    
                CallStudentHandler handlerB = new CallStudentHandler(CallStudent.CallStudentB);
                CallStudent.CallStudentName("Student B", handlerB);
    
                CallStudentHandler handlerC = new CallStudentHandler(CallStudent.CallStudentC);
                CallStudent.CallStudentName("Student C", handlerC);
                Console.WriteLine();
    
                //用匿名函数的方法替代上述写法
                CallStudentHandler handler1 = new CallStudentHandler(
                    delegate(string name)
                    {
                        Console.WriteLine("{0}", name);
                    }); //用匿名的方式把方法名给去掉
                handler1.Invoke("Student A");
    
                //用lambda表达式的方式1 替代上述写法
                //Lambda表达式的本质就是一个匿名方法
                CallStudentHandler handler2= new CallStudentHandler(
                    (string name)=>
                    {
                        Console.WriteLine("{0}", name);
                    }); //用lambda表达式的方式把delegate换成=>  箭头左边是参数列表,右边是方法体
                handler2.Invoke("Student A");
    
                //用lambda表达式的方式2
                CallStudentHandler handler3 = new CallStudentHandler(
                    (name) =>
                    {
                        Console.WriteLine("{0}", name);
                    }); //去掉参数类型
                handler3.Invoke("Student A");
    
                //用lambda表达式的方式3
                CallStudentHandler handler4 =(name) =>
                    {
                        Console.WriteLine("{0}", name);
                    }; //去掉 new CallStudentHandler
                handler4.Invoke("Student A");
    
                //用lambda表达式的方式4
                CallStudentHandler handler5 = (name) => Console.WriteLine("{0}", name);   //去掉{},适用于方法体只有一行
                //去掉{}后,如果方法体只有一行,带返回值的去掉return
                handler5.Invoke("Student A");
    
                Console.ReadLine();
            }
    

      

上一篇:《Spring源码深度解析》二


下一篇:iOS经典面试题(转)(转)