zoukankan      html  css  js  c++  java
  • C#中使用委托

    C#中使用委托

    在C#中可以将委托看作一种新的类型,它是用来定义需要用来传递的方法的签名。类似于C++中的函数指针,它定义函数的输入参数和输出参数,是一批相似方法的代名词。但是为了种种原因,例如代码安全。所以 .Net Framework 在语法上不允许直接传递方法或叫函数,如果确实要这么处理,那就需要将方法包装成为一个新类型(委托)对象中。委托是一种特殊的对象,其他的对象包含的是数据和方法。但委托包含的是方法的细节。

    我们通常习惯于向一个方法传递数值或对象,但是有时我们也希望向这个方法传递另一个方法,但这个方法的名称在设计时却是不确定的,只有到了运行时才能确定。这时就可以把要传递的方法用委托来定义,在使用时要把他看作是一个方法的代名词。


    使用委托的步骤:
    1、声明委托,定义参数列表和返回类型。
    2、实例化委托,同时将一个符合委托声明参数的方法名称传递给委托。
    3、调用委托,简单来说就象使用方法一样来使用委托的实例。

    如下例:

     1 using System;
     2 using System.Collections;
     3 
     4 namespace Exam
     5 {
     6     // 自定义类
     7     public class Class1
     8     {
     9         private string name;
    10         public string Name
    11         {
    12             set { name = value; }
    13             get { return name; }
    14         }
    15     }
    16 
    17     // 声明一个委托用来代表所有输入参数是Class1,输出参数是string的方法。
    18     public delegate string Delegate(Class1 cls);
    19 
    20     class Class2
    21     {
    22         [STAThread]
    23         static void Main(string[] args)
    24         {
    25             // 实例化委托,同时指定这个委托实例所代表的方法名就是这个类
    26             // 的一个静态方法getName,注意这里不需要指定方法的参数。
    27             Delegate test = new Delegate(getName);
    28 
    29             Class1 c1 = new Class1();
    30             c1.Name = "Class1";
    31 
    32             // 调用委托test所代表的方法,同时传递他需要的参数c1。
    33             Console.WriteLine(test(c1));
    34 
    35             Console.ReadKey();
    36         }
    37 
    38         static string getName(Class1 cls)
    39         {
    40             return cls.Name;
    41         }
    42     }
    43 }
    44 

    最后,委托的实例可以表示任何类型的任何对象上的实例方法或静态方法,只要方法签名和委托签名相同即可。


    多播委托

    上面使用的委托只包含了一个方法,调用委托时执行方法的次数也只有一次。其实,如果一个委托它的返回值是 void 那么编译器就自动把它当作一个多播委托来处理。什么意思呢?也就是可以使用 += 方法向这个委托的实例添加其他方法。那么在使用这个实例时就会执行它所代表的所有方法。

    例如:
     1 using System;
     2 using System.Collections;
     3 
     4 namespace Exam
     5 {
     6     // 无返回值的委托是多播委托
     7     public delegate void CountMethodDelegate(int a, int b);
     8 
     9     class Class1
    10     {
    11 
    12         // 加法
    13         static void Plus(int a, int b)
    14         {
    15             Console.WriteLine(String.Format("A:{0} + B:{1} = {2}",a,b,a+b));
    16         }
    17 
    18         // 减法
    19         static void Minus(int a, int b)
    20         {
    21             Console.WriteLine(String.Format("A:{0} - B:{1} = {2}", a, b, a - b));
    22         }
    23 
    24         // 乘法
    25         static void Multiply(int a, int b)
    26         {
    27             Console.WriteLine(String.Format("A:{0} * B:{1} = {2}", a, b, a * b));
    28         }
    29         
    30         // 除法
    31         static void Divide(int a, int b)
    32         {
    33             Console.WriteLine(String.Format("A:{0} / B:{1} = {2}", a, b, a / b));
    34         }
    35 
    36         [STAThread]
    37         static void Main(string[] args)
    38         {
    39             int A, B;
    40             A = 100;
    41             B = 7;
    42 
    43             // 连续向这个委托的实例添加方法。
    44             CountMethodDelegate test = new CountMethodDelegate(Plus);
    45             test += new CountMethodDelegate(Minus);
    46             test += new CountMethodDelegate(Multiply);
    47             test += new CountMethodDelegate(Divide);
    48 
    49 
    50             // 调用委托test所代表的方法,同时传递他需要的参数A和B。
    51             // 一次调用,执行所有方法。
    52             test(A, B);
    53 
    54             Console.ReadKey();
    55         }
    56     }
    57 }
    58 

    多播委托是一个派生于 System.MulticastDelegate 的类,它派生于基类 System.Delegate。它的其他成员允许把多个方法调用链接在一起,成为一个列表。但这并不代表执行这些方法的顺序会按照添加时的顺序执行,要避免编写依赖特定顺序调用方法的代码。

    洪虎

    2006-10-2 更新
  • 相关阅读:
    线段树小结
    线段树 区间合并
    线段树
    线段树离散化+区间修改
    线段树模板

    geatpy
    基于Anaconda 安装 geatpy 和 tensorflow
    Python 求“元组、列表、字典、数组和矩阵”的大小
    np.array()和np.mat()区别
  • 原文地址:https://www.cnblogs.com/eric1394/p/520242.html
Copyright © 2011-2022 走看看