zoukankan      html  css  js  c++  java
  • C# 委托 事件

    一:什么叫委托

    通过反射发现,委托其实是一个类,继承自System.MulticastDelegate,但是System.MulticastDelegate这个类是特殊类,不能被继承

    二:委托的声明 

    1 public delegate void NoReturnNoParaOutClass();
    2  public class MyDelete
    3  {
    4       public delegate void NoReturnNoPara<T>(T t);
    5       public delegate void NoReturnNoPara();
    6       public delegate void NoReturnWithPara(int x, int y);
    7       public delegate int WithReturnNoPara();
    8       public delegate string WithReturnWithPara(out int x, ref int y);
    9     }

    委托可以声明在类外面,可以声明再类里面

    三:委托的实例和调用 

     1 private int GetSomething()
     2         {
     3             return 1;
     4         }
     5         private int GetSomething2()
     6         {
     7             return 2;
     8         }
     9 
    10         private int GetSomething3()
    11         {
    12             return 3;
    13         }
    14         private void DoNothing()
    15         {
    16             Console.WriteLine("This is DoNothing");
    17         }
    18         private static void DoNothingStatic()
    19         {
    20             Console.WriteLine("This is DoNothingStatic");
    21         }
    22         public string ParaReturn(out int x, ref int y)
    23         {
    24             throw new Exception();
    25         }
     1 //多种途径实例化,要求传递一个参数类型,返回值都跟委托一致的方法
     2 {
     3    WithReturnWithPara method = new WithReturnWithPara(ParaReturn);
     4    int x = 0;
     5    int y = 0;
     6    var dd = method.Invoke(out x, ref y);
     7  }
     8 //begininvoke
     9 {
    10    WithReturnNoPara method = new WithReturnNoPara(this.GetSomething);
    11    int iResult = method.Invoke();
    12    iResult = method();
    13    var result = method.BeginInvoke(null, null);//异步调用
    14    method.EndInvoke(result);
    15 }
    16 {
    17    NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
    18    //委托实力的调用,参数和委托约束的一致
    19     method.Invoke(); //1
    20     //method(); //2
    21     //method.BeginInvoke(null, null); //3
    22     //this.DoNothing(); //1,2,3都等同于this.DoNothing
    23 
    24 }
    25 {
    26      NoReturnNoPara method = new NoReturnNoPara(DoNothingStatic);
    27 }
    28 {
    29     NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced);
    30 }
    31 {
    32     NoReturnNoPara method = new NoReturnNoPara(new Student().Study);
    33 }

    四:为什么要使用委托

    有时候我们声明一个方法,直接调用蛮好的,为啥还要使用委托,然后还要先声明,再实例化,再inovke调用呢?

    下面我们举个例子,比如一个人问好这件事情,不同人问候方式不一样,我们会先定义一个类型,如枚举

    1 public enum PeopleType
    2  {
    3         Chinese,
    4         America,
    5         Japanese
    6  }

    然后通过不同的类型来判断问候方式不同,如下

     1 /// 为不同的人,进行不同的问候
     2         /// 传递变量--判断一下----执行对应的逻辑
     3         /// </summary>
     4         /// <param name="name"></param>
     5         /// <param name="peopleType"></param>
     6         public void SayHi(string name, PeopleType peopleType)
     7         {
     8             switch (peopleType)
     9             {
    10                 case PeopleType.Chinese:
    11                     Console.WriteLine($"{name}晚上好");
    12                     break;
    13                 case PeopleType.America:
    14                     Console.WriteLine($"{name},good evening");
    15                     break;
    16                 case PeopleType.Japanese:
    17                     Console.WriteLine($"{name},&&%*^^***@@@&&&&");
    18                     break;
    19                 default:
    20                     throw new Exception("wrong peopleType"); //遇到异常报错
    21             }
    22         }

    这样做的好处是:以后如果增加公共逻辑等比较容易,但是如果类型比较多,这个方法会变成无限制改动,导致方法难以维护,于是很多人想着增加分支,就增加方法--不影响别的方法的思路来改善

     1 public void SayHiChinese(string name)
     2   {
     3          Console.WriteLine($"{name}晚上好");
     4   }
     5   public void SayHiJapanese(string name)
     6   {
     7          Console.WriteLine($"{name},&&%*^^***@@@&&&&");
     8   }
     9   public void SayHiAmerican(string name)
    10   {
    11           Console.WriteLine($"{name},good evening");
    12   }

    然后上层判断调用

    这样做的好处是:修改某个方法--不影响别的方法 ,但是缺点却是:增加公共逻辑---多个方法就有很多重复代码

    那么我们想:既增加逻辑方便,又维护简单,鱼肉熊掌,如何兼得呢?

    我们可以把相应的逻辑做为参数传进来,这样就解决了我们的问题

    具体我们可以按照以下来做:

    1 public void SayHiPerfact(string name, SayHiDeletegate method)
    2   {
    3       Console.WriteLine("增加开始日志");
    4       method.Invoke(name);
    5       Console.WriteLine("增加结束日志");          
    6   }
    7   public delegate void SayHiDeletegate(string name);

    然后调用的时候如下:

    1   SayHiDeletegate method = new SayHiDeletegate(SayHiChinese);

    这样就做到了

    1:逻辑解耦,方便维护 

    2:代码重构,去掉重复

    其实这也是我们选择使用委托的两大优点

    注意:以上我们纯粹为了定义委托而定义委托,其实框架已经我们帮我们定义了Action 和Func这两个委托,Action是没有返回值,Func是有返回值的,这两个委托类已经足够我们使用了,所以有时候我们使用的时候,没有必要自己再去定义,而直接使用即可

  • 相关阅读:
    李宏毅机器学习课程笔记-9.3RNN的应用
    李宏毅机器学习课程笔记-9.2如何训练RNN
    李宏毅机器学习课程笔记-9.1循环神经网络RNN入门
    李宏毅机器学习课程笔记-8.2图神经网络(Spatial-based Convolution)
    李宏毅机器学习课程笔记-7.4基于CNN和PyTorch的食物图片分类
    PyTorch入门:基于LeNet5和CIFAR10的图片分类
    PyTorch入门:使用PyTorch搭建神经网络LeNet5
    李宏毅机器学习课程笔记-8.1图神经网络入门
    李宏毅机器学习课程笔记-7.3CNN应用案例
    李宏毅机器学习课程笔记-7.2CNN学到了什么
  • 原文地址:https://www.cnblogs.com/kliine/p/10168184.html
Copyright © 2011-2022 走看看