c# 委托详解

2019-12-30 16:31:48王旭

委托是一个类型。C#中的委托是面向对象的,并且它是类型安全的 当创建委托实例的时候,创建的实例会包含一个调用列表,在调用列表中可以包含多个方法。每个方法称作一个调用实体。调用实体可以是静态方法,也可以是实例方法。如果是实例方法,则该调用实体包含调用该实例方法的实例。委托并不关心它所调用方法所属的类,它只关心被调用方法与委托的类型是否兼容。 下面是代码实例:


using System;
namespace LycheeTest{
 public delegate void D(int a, int b);
 public class Test {
 public D myDelegate;
 public Test() {
  myDelegate = new D(Show1);
 }
 private static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被调用,两个实参相加的值是:{0}", a + b);
 }
 private void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被调用,两个实参相加的值是:{0}", a + b);
 }
 private void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被调用,两个实参相加的值是:{0}", a + b);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test myT = new Test();
  myT.myDelegate(33, 22);
  Console.ReadKey();
 }
 }
}

这段代码演示的是最简单的一种委托形式。委托类型可以定义在类的外部,也可以定义在类的内部。 本段代码是定义在类的外部。第 3 行代码定义的就是一个委托类型,委托类型的关键字是 delegate,关键字前是委托类型的访问权限修饰符。关键字后是委托类型的返回类型,这个返回类型规定与委托类型兼容 的方法的返回类型必须与之相同。返回类型之后是委托类型的名称。接下来是形参列表,它指定与委托类 型兼容的方法的参数类型和个数必须与之相同。第 5 行代码定义了一个委托类型的变量,它是一个实例字段,访问权限是 public 的。注意委托类型字段的访问权限一定要比委托类型的访问权限低或与委托类型的访问权限相同才可以。第 9 行、第 12 行和第 15 行代码定义了三个方法。其中第 9 行代码是一个静态方法。因为这段代码演示的是最简单的委托使用方法,所以只使用了其中的静态方法。在第 6 行的构造方法中,实例化了委托类型的变量,注意为委托变量的调用列表添加方法,只需要向其构造方法中传递方法名称即可。这是为委托添加调用方法的最基本的一种方法。第 21 行定义了 Test 类的一个实例,然后第 22 行调用了类的委托成员。在调用委托成员的时候,需要向其形参列表传递实参。这就是最基本的委托的使用方法。这段代码的执行结果如下:

方法 Show1 被调用,两个实参相加的值是:55

下面再介绍一种委托类型的使用方法,实例代码如下:


using System;
namespace LycheeTest {
 public delegate void D(int a, int b);
 public class Test {
 public static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被调用,两个实参相加的值是:{0}", a + b);
 }
 public void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被调用,两个实参相加的值是:{0}", a + b);
 }
 public void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被调用,两个实参相加的值是:{0}", a + b);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test myT = new Test();
  D myDelegate = new D(Test.Show1);
  D myDelegate1 = new D(myT.Show2);
  D myDelegate2 = new D(myT.Show3);
  myDelegate(22, 33);
  myDelegate1(33, 44);
  myDelegate2(55, 66);
  Console.ReadKey();
 }
 }
}