zoukankan      html  css  js  c++  java
  • 浅谈C#委托的用法-delegate[转]

    一、委托的概念

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

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

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

    二、委托的声明

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

    三、委托的使用

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

      四、委托的意义

        1、没有委托就没有异步

        2、解耦

        3、高效扩展

      1 public class CallStudent
       2     {
       3         //方法1
       4         public static void CallStudentA(string name)
       5         {
       6             Console.WriteLine("{0}", name);
       7         }
       8         //方法2
       9         public static void CallStudentB(string name)
      10         {
      11             Console.WriteLine("{0}", name);
      12         }
      13         //方法3
      14         public static void CallStudentC(string name)
      15         {
      16             Console.WriteLine("{0}", name);
      17         }
      18 
      19         //传值的方式,根据值来决定行为,所有的方法全部耦合在一起,
      20         //如果要增加方法则需要修改该方法,不便于方法的封装、扩展
      21         public static void CallStudentName(string name, StudentType type)
      22         {
      23             if (type == StudentType.A)
      24             {
      25                 Console.WriteLine("{0}", name);
      26             }
      27             else if (type == StudentType.B)
      28             {
      29                 Console.WriteLine("{0}", name);
      30             }
      31             else if (type == StudentType.C)
      32             {
      33                 Console.WriteLine("{0}", name);
      34             }
      35         }
      36 
      37         //用委托的方式来实现传递方法,如果要增加方法,只需要重新增加一个方法就好
      38         public static void CallStudentName(string name, CallStudentHandler handler)
      39         {
      40             handler.Invoke(name);
      41         }
      42     }
      43 
      44     public delegate void CallStudentHandler(string name);
      45 
      46     public enum StudentType
      47     {
      48         A,
      49         B,
      50         C
      51     }
      
      1 static void Main(string[] args)
       2         {
       3             //用不同的值来区分不同的方法
       4             CallStudent.CallStudentName("Student A",StudentType.A );
       5             CallStudent.CallStudentName("Student B", StudentType.B);
       6             CallStudent.CallStudentName("Student C", StudentType.C );
       7             Console.WriteLine();
       8 
       9             //用委托的方式传递多个方法
      10             CallStudentHandler handlerA = new CallStudentHandler(CallStudent.CallStudentA);
      11             CallStudent.CallStudentName("Student A", handlerA);
      12 
      13             CallStudentHandler handlerB = new CallStudentHandler(CallStudent.CallStudentB);
      14             CallStudent.CallStudentName("Student B", handlerB);
      15 
      16             CallStudentHandler handlerC = new CallStudentHandler(CallStudent.CallStudentC);
      17             CallStudent.CallStudentName("Student C", handlerC);
      18             Console.WriteLine();
      19 
      20             //用匿名函数的方法替代上述写法
      21             CallStudentHandler handler1 = new CallStudentHandler(
      22                 delegate(string name)
      23                 {
      24                     Console.WriteLine("{0}", name);
      25                 }); //用匿名的方式把方法名给去掉
      26             handler1.Invoke("Student A");
      27 
      28             //用lambda表达式的方式1 替代上述写法
      29             //Lambda表达式的本质就是一个匿名方法
      30             CallStudentHandler handler2= new CallStudentHandler(
      31                 (string name)=>
      32                 {
      33                     Console.WriteLine("{0}", name);
      34                 }); //用lambda表达式的方式把delegate换成=>  箭头左边是参数列表,右边是方法体
      35             handler2.Invoke("Student A");
      36 
      37             //用lambda表达式的方式2
      38             CallStudentHandler handler3 = new CallStudentHandler(
      39                 (name) =>
      40                 {
      41                     Console.WriteLine("{0}", name);
      42                 }); //去掉参数类型
      43             handler3.Invoke("Student A");
      44 
      45             //用lambda表达式的方式3
      46             CallStudentHandler handler4 =(name) =>
      47                 {
      48                     Console.WriteLine("{0}", name);
      49                 }; //去掉 new CallStudentHandler
      50             handler4.Invoke("Student A");
      51 
      52             //用lambda表达式的方式4
      53             CallStudentHandler handler5 = (name) => Console.WriteLine("{0}", name);   //去掉{},适用于方法体只有一行
      54             //去掉{}后,如果方法体只有一行,带返回值的去掉return
      55             handler5.Invoke("Student A");
      56 
      57             Console.ReadLine();
      58         }

      参考:https://www.cnblogs.com/goldendragon/p/9922592.html

  • 相关阅读:
    Flex 布局语法教程
    2017年总结的前端文章——border属性的多方位应用和实现自适应三角形
    html 里 checkbox里 只要选中就会自动添加checked=“checked”么?
    jQuery遍历DOM
    checkbox 全选操作
    ubuntu下安装jdk
    ubuntu下安装nodejs
    nodejs express route 的用法
    聊天室业务分析
    一般使用场景
  • 原文地址:https://www.cnblogs.com/lucode/p/12173994.html
Copyright © 2011-2022 走看看