委托是一种安全封装方法(引用方法)的类型,可以与具有兼容签名的任何方法关联。您可以通过委托调用方法。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用您的方法。

委托类型声明需要delegate 关键字,格式如下:

访问修饰符 delegate 返回类型 委托名称(参数列表);

如:public delegate void TestDelegate(string message);

 

通过将委托与命名方法或匿名方法关联,可以实例化委托。与委托的签名(由返回类型和参数组成)匹配的任何可访问类或结构中的任何方法都可以分配给该委托。方法可以是命名方法,也可以是匿名方法。这样就可以通过编程方式来更改方法调用,还可以向现有类中插入新代码。只要知道委托的签名,就可以分配您自己的方法。

注意:

在方法重载的上下文中,方法的签名不包括返回值。但在委托的上下文中,签名的确包括返回值。换句话说,方法和委托必须具有相同的返回值。

 

将方法作为参数进行引用的能力使委托成为定义回调方法的理想选择。例如,可以向排序算法传递对比较两个对象的方法的引用。分离比较代码使得可以采用更通用的方式编写算法。

为了与命名方法一起使用,委托必须用具有可接受签名的方法进行实例化。有关方法签名中允许的方差度的更多信息,请参见委托中的协变和逆变。为了与匿名方法一起使用,委托和与之关联的代码必须一起声明。示例:

代码
using System;
// Declare delegate -- defines required signature:
delegate void SampleDelegate(string message);

class MainClass
{
    
// Regular method that matches signature:
    static void SampleDelegateMethod(string message)
    {
        Console.WriteLine(message);
    }

    
static void Main()
    {
        
// Instantiate delegate with named method:
        SampleDelegate d1 = SampleDelegateMethod;
        
// Instantiate delegate with anonymous method:
        SampleDelegate d2 = delegate(string message)
        { 
            Console.WriteLine(message); 
        };

        
// Invoke delegate d1:
        d1("Hello");
        
// Invoke delegate d2:
        d2(" World");
    }
}

 

委托概述

委托具有以下特点:

  • 委托类似于 C++ 函数指针,但它们是类型安全的。

  • 委托允许将方法作为参数进行传递。

  • 委托可用于定义回调方法。

  • 委托可以链接在一起;例如,可以对一个事件调用多个方法。

  • 方法不必与委托签名完全匹配。有关更多信息,请参见Covariance and Contravariance委托中的协变和逆变(C# 编程指南)

  • C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。C# 3.0 引入了 Lambda 表达式,利用它们可以更简练地编写内联代码块。匿名方法和 Lambda 表达式(在某些上下文中)都可编译为委托类型。这些功能统称为匿名函数。有关 Lambda 表达式的更多信息,请参见匿名函数(C# 编程指南)

 

使用委托

委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似。与 C 中的函数指针不同,委托是面向对象的、类型安全的和保险的。委托的类型由委托的名称定义。

构造委托对象时,通常提供委托给包装的方法的名称或使用匿名方法。实例化委托后,委托将把对它进行的方法调用 传递给方法。调用方传递给委托的参数被传递给方法,来自方法的返回值(如果有)由委托返回给调用方。这被称为调用委托。可以将一个实例化的委托视为被包装的方法本身来调用该委托。

示例:

代码
public delegate void Del(string message);

// Create a method for a delegate.
public static void DelegateMethod(string message)
{
    System.Console.WriteLine(message);
}

// Instantiate the delegate.
Del handler = DelegateMethod;

// Call the delegate.
handler("Hello World");

 

委托类型派生自 .NET Framework 中的 Delegate 类。委托类型是密封的,不能从 Delegate 中派生委托类型,也不可能从中派生自定义类。由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性。这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托。这称为异步回调,是在较长的进程完成后用来通知调用方的常用方法。以这种方式使用委托时,使用委托的代码无需了解有关所用方法的实现方面的任何信息。此功能类似于接口所提供的封装。有关更多信息,请参见何时使用委托而不使用接口

回调的另一个常见用法是定义自定义的比较方法并将该委托传递给排序方法。它允许调用方的代码成为排序算法的一部分。下面的示例方法使用 Del 类型作为参数:

代码
public void MethodWithCallback(int param1, int param2, Del callback)
{
    callback(
"The number is: " + (param1 + param2).ToString());
}

public void Show()
{
    MethodWithCallback(
12, handler);
}

 

 

posted on 2010-07-28 16:11  Kein  阅读(220)  评论(0编辑  收藏  举报