zoukankan      html  css  js  c++  java
  • 我看委托

          知道C#的“委托”名词很久了,一直都没有需求去了解它,最近因为要写的系统以及nbpm萌生了了解它的想法。
          初步看了一下委托,第一感觉委托本质上就是C/C++中的函数指针。不同的是委托是面向对象,其构造更复杂和灵活,但掌握了之后使用更方便。同时函数指针只能是静态方法,而委托可以是静态方法,也可以是实例方法。
          委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。
    一、基本用法:
          委托最基本的概念和方法使用下面的例子应该很明了:

     1using System;
     2namespace 委托
     3{
     4  delegate int NumOpe(int a,int b); //委托声明
     5  class Class1
     6  {
     7    static void Main(string[] args)
     8    {
     9      Class1 c1 = new Class1();
    10      NumOpe p1 = new NumOpe(c1.Add); //委托实例化
    11      Console.WriteLine(p1(1,2)); //委托调用
    12      Console.ReadLine();
    13    }

    14    private int Add(int num1,int num2)
    15    {
    16      return(num1+num2);
    17    }

    18  }

    19}

          例中,委托NumOpe引用了方法Add。
          委托声明了以后,就可以象类一样进行实例化,实例化时把要引用的方法(如:Add)做为参数,这样委托和方法就关联了起来,就可以用委托来引用方法了。
          委托和所引用的方法必须保持一致:
          1、参数个数、类型、顺序必须完全一致。
          2、返回值必须一致。
    二、委托的应用-事件
          委托的一个最常用的应用就是事件。
          事件和处理方法之间是怎么联系起来的呢?委托就是他们中间的桥梁,事件发生时,委托会知道,然后将事件传递给处理方法,处理方法进行相应处理。
          比如在WinForm中最常见的是按钮的Click事件,它是这样委托的:
          this.button1.Click += new System.EventHandler(this.button1_Click);
          按按钮后就会出发button1_Click方法进行处理。EventHandler就是系统类库里已经声明的一个委托。
    三、自定义事件及其处理
          自定义事件是更委托的复杂的应用。
          EventHandler以及其它自定义的事件委托都是一类特殊的委托,他们有相同的形式:
          delegate void 事件委托名(object sender,EventArgs e);
          object用来传递事件的发生者,比如二中的Button控件就是一个事件发生者;EventArgs用来传递事件的细节。
          下面是两个例子:
          例程二:

     1using System;
     2namespace 最简单的自定义事件
     3{
     4  /// <summary>
     5  /// 事件发送类
     6  /// </summary>

     7  class Class1
     8  {
     9    public delegate void UserRequest(object sender,EventArgs e); //定义委托
    10    public event UserRequest OnUserRequest; //定义一个委托类型的事件
    11    public void run()
    12    {
    13      while(true)
    14      {
    15        if(Console.ReadLine()=="a")
    16        {//事件监听
    17          OnUserRequest(this,new EventArgs()); //产生事件
    18        }

    19      }

    20    }

    21  }

    22  /// <summary>
    23  /// 事件接收类
    24  /// </summary>

    25  class Class2
    26  {
    27    static void Main(string[] args)
    28    {
    29      Class1 c1 = new Class1();
    30      c1.OnUserRequest += new Class1.UserRequest(c1_OnUserRequest); //委托实例化后绑定到事件
    31      c1.run();
    32    }

    33    private static void c1_OnUserRequest(object sender, EventArgs e)
    34    {//事件处理方法
    35      Console.WriteLine("\t你触发了事件!");
    36    }

    37  }

    38}

          例程三:

     1using System;
     2namespace 带事件数据的事件
     3{
     4  /// <summary>
     5  /// 带事件数据的事件类,从EventArgs继承
     6  /// </summary>

     7  class OnUserRequestEventArgs:EventArgs
     8  {
     9    private string inputText;
    10    public string InputText
    11    {
    12      get
    13      {
    14        return inputText;
    15      }

    16      set
    17      {
    18        inputText = value;
    19      }

    20    }

    21  }

    22  /// <summary>
    23  /// 事件发送类
    24  /// </summary>

    25  class Class1
    26  {
    27    public delegate void UserRequest(object sender,OnUserRequestEventArgs e);
    28    public event UserRequest OnUserRequest;
    29    public void run()
    30    {
    31      while(true)
    32      {
    33        Console.WriteLine("请输入内容:");
    34        string a=Console.ReadLine();
    35        //if(a=="a")
    36        //{
    37        OnUserRequestEventArgs e1 = new OnUserRequestEventArgs();
    38        e1.InputText = a;
    39        OnUserRequest(this,e1);
    40        //}
    41      }

    42    }

    43  }

    44  /// <summary>
    45  /// 事件接收类
    46  /// </summary>

    47  class Class2
    48  {
    49    [STAThread]
    50    static void Main(string[] args)
    51    {
    52      Class1 c1 = new Class1();
    53      c1.OnUserRequest += new Class1.UserRequest(c1_OnUserRequest);
    54      c1.run();
    55    }

    56    private static void c1_OnUserRequest(object sender, OnUserRequestEventArgs e)
    57    {
    58      Console.WriteLine("\t你输入的是:"+e.InputText);
    59    }

    60  }

    61}
    四、什么时候用委托: 
    • 当封装静态方法可取时。
    • 当使用事件设计模式时。
    • 当调用主不需要访问实现该方法的对象中的其他属性、方法或接口时
    • 需要方便的组合时。
    • 当类可能需要该方法的多个实现时。
  • 相关阅读:
    BestCoder Round #84
    codeforces#689BMike and Shortcuts
    POJ2985 并查集+线段树 求第k大的数
    Trie树模板 POJ1056
    新建zabbix数据库
    python输出菱形
    wmi获取计算机信息
    python测试IP地址是否ping通
    手机安装python环境
    Centos 8 安装zabbix 爬坑
  • 原文地址:https://www.cnblogs.com/badwood316/p/773443.html
Copyright © 2011-2022 走看看