Delegate 类

表示委托,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。

**命名空间:**System
**程序集:**mscorlib(在 mscorlib.dll 中)

语法

声明
<SerializableAttribute> _
<ClassInterfaceAttribute(ClassInterfaceType.AutoDual)> _
<ComVisibleAttribute(True)> _
Public MustInherit Class Delegate
    Implements ICloneable, ISerializable
用法
Dim instance As Delegate
[SerializableAttribute] 
[ClassInterfaceAttribute(ClassInterfaceType.AutoDual)] 
[ComVisibleAttribute(true)] 
public abstract class Delegate : ICloneable, ISerializable
[SerializableAttribute] 
[ClassInterfaceAttribute(ClassInterfaceType::AutoDual)] 
[ComVisibleAttribute(true)] 
public ref class Delegate abstract : ICloneable, ISerializable
/** @attribute SerializableAttribute() */ 
/** @attribute ClassInterfaceAttribute(ClassInterfaceType.AutoDual) */ 
/** @attribute ComVisibleAttribute(true) */ 
public abstract class Delegate implements ICloneable, ISerializable
SerializableAttribute 
ClassInterfaceAttribute(ClassInterfaceType.AutoDual) 
ComVisibleAttribute(true) 
public abstract class Delegate implements ICloneable, ISerializable

备注

Delegate 类是委托类型的基类。然而,只有系统和编译器可以显式地从 Delegate 类或 MulticastDelegate 类派生。此外,还不允许从委托类型派生新类型。Delegate 类不是委托类型,该类用于派生委托类型。

大多数语言实现 delegate 关键字,这些语言的编译器能够从 MulticastDelegate 类进行派生;所以,用户应当使用语言所提供的 delegate 关键字。

委托类型的声明建立了一个协定,该协定指定一个或多个方法的签名。委托是具有对以下内容的引用的委托类型的实例:

  • 某种类型的实例方法和可分配给该类型的目标对象。

  • 某种类型的实例方法(包含在形参表中公开的隐藏 this 参数)。该委托称为开放式实例委托。

  • 静态方法。

  • 静态方法和可分配给该方法的第一个参数的目标对象。该委托称为通过其第一个参数关闭。

有关委托绑定的更多信息,请参见 通用类型系统中的委托CreateDelegate(Type,Object,MethodInfo,Boolean)

提示

在 .NET Framework 1.0 版和 1.1 版中,仅当方法的签名与委托类型指定的签名完全匹配时,委托才可以表示方法。因此,仅支持上面列表中的第一项和第三项,且第一项要求与类型完全匹配。

当委托表示通过其第一个参数关闭的实例方法(最常见的情况)时,委托存储对该方法的入口点的引用和对称为目标的对象(该对象具有可分配给定义该方法的类型的类型)的引用。当委托表示开放式实例方法时,它存储对该方法入口点的引用。委托签名必须在其形参表中包括隐藏的 this 参数;在这种情况下,委托不具有对目标对象的引用,必须在调用委托时提供目标对象。

当委托表示静态方法时,委托存储对该方法入口点的引用。当委托表示通过其第一个参数关闭的静态方法时,委托存储对该方法入口点的引用和对目标对象(该对象可分配给方法第一个参数的类型)的引用。调用该委托时,静态方法的第一个参数接收目标对象。

委托的调用列表就是已排序的委托集,其中列表的每个元素恰好调用该委托表示的一个方法。调用列表可以包含重复的方法。在调用期间,按方法出现在调用列表中的顺序来调用它们。委托试图调用其调用列表中的每个方法,而重复方法在调用列表中出现一次就调用一次。委托是不可变的;一旦创建,委托的调用列表便无法更改。

委托被称作多路广播委托或可组合委托,因为委托可以调用一种或多种方法,并且可以用在组合操作中。

合并操作(如 CombineRemove)并不改变现有委托。相反,这样的操作返回一个新委托,其中包含操作结果、未更改的委托或 空引用(在 Visual Basic 中为 Nothing)。当合并操作的结果是没有引用任何方法的委托时,该操作返回 空引用(在 Visual Basic 中为 Nothing)。当所请求的操作无效时,合并操作返回未更改的委托。

如果所调用的方法引发异常,则方法停止执行,并将异常向回传递给委托的调用方,且不再调用调用列表中其余的方法。捕捉调用方的异常并不改变此行为。

当委托所调用的方法的签名包含返回值时,委托返回调用列表中最后一个元素的返回值。当签名包含由引用传递的参数时,该参数的最终值就是调用列表中每个方法的结果,这些方法依序执行并更新参数的值。

编译器为委托提供两种其他方法:BeginInvokeEndInvoke。有关这些方法的更多信息,请参见“使用异步方式调用同步方法”。

在 C 或 C++ 中与委托最为相似的是函数指针。委托可以表示静态方法或实例方法。当委托表示实例方法时,委托不仅存储对方法入口点的引用,还存储对类实例的引用。与函数指针不同,委托是面向对象和类型安全的。

示例

下面的示例说明如何定义标准委托。

Imports System

Public Class SamplesDelegate

   ' Declares a delegate for a method that takes in an int and returns a String.
   Delegate Function myMethodDelegate(myInt As Integer) As [String]

   ' Defines some methods to which the delegate can point.
   Public Class mySampleClass

      ' Defines an instance method.
      Public Function myStringMethod(myInt As Integer) As [String]
         If myInt > 0 Then
            Return "positive"
         End If
         If myInt < 0 Then
            Return "negative"
         End If
         Return "zero"
      End Function 'myStringMethod

      ' Defines a static method.
      Public Shared Function mySignMethod(myInt As Integer) As [String]
         If myInt > 0 Then
            Return "+"
         End If
         If myInt < 0 Then
            Return "-"
         End If
         Return ""
      End Function 'mySignMethod
   End Class 'mySampleClass

   Public Shared Sub Main()

      ' Creates one delegate for each method.
      Dim mySC As New mySampleClass()
      Dim myD1 As New myMethodDelegate(AddressOf mySC.myStringMethod)
      Dim myD2 As New myMethodDelegate(AddressOf mySampleClass.mySignMethod)

      ' Invokes the delegates.
      Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 5, myD1(5), myD2(5))
      Console.WriteLine("{0} is {1}; use the sign ""{2}"".", - 3, myD1(- 3), myD2(- 3))
      Console.WriteLine("{0} is {1}; use the sign ""{2}"".", 0, myD1(0), myD2(0))

   End Sub 'Main

End Class 'SamplesDelegate 


'This code produces the following output:
' 
'5 is positive; use the sign "+".
'-3 is negative; use the sign "-".
'0 is zero; use the sign "".

using System;
public class SamplesDelegate  {

   // Declares a delegate for a method that takes in an int and returns a String.
   public delegate String myMethodDelegate( int myInt );

   // Defines some methods to which the delegate can point.
   public class mySampleClass  {

      // Defines an instance method.
      public String myStringMethod ( int myInt )  {
         if ( myInt > 0 )
            return( "positive" );
         if ( myInt < 0 )
            return( "negative" );
         return ( "zero" );
      }

      // Defines a static method.
      public static String mySignMethod ( int myInt )  {
         if ( myInt > 0 )
            return( "+" );
         if ( myInt < 0 )
            return( "-" );
         return ( "" );
      }
   }

   public static void Main()  {

      // Creates one delegate for each method.
      mySampleClass mySC = new mySampleClass();
      myMethodDelegate myD1 = new myMethodDelegate( mySC.myStringMethod );
      myMethodDelegate myD2 = new myMethodDelegate( mySampleClass.mySignMethod );

      // Invokes the delegates.
      Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", 5, myD1( 5 ), myD2( 5 ) );
      Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", -3, myD1( -3 ), myD2( -3 ) );
      Console.WriteLine( "{0} is {1}; use the sign \"{2}\".", 0, myD1( 0 ), myD2( 0 ) );
   }

}


/*
This code produces the following output:
 
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/ 
using namespace System;
delegate String^ myMethodDelegate( // Declares a delegate for a method that takes in an int and returns a String.
int myInt );

// Defines some methods to which the delegate can point.
ref class mySampleClass
{
public:

   // Defines an instance method.
   String^ myStringMethod( int myInt )
   {
      if ( myInt > 0 )
            return ("positive");

      if ( myInt < 0 )
            return ("negative");

      return ("zero");
   }


   // Defines a static method.
   static String^ mySignMethod( int myInt )
   {
      if ( myInt > 0 )
            return ("+");

      if ( myInt < 0 )
            return ("-");

      return ("");
   }

};

int main()
{
   
   // Creates one delegate for each method.
   mySampleClass^ mySC = gcnew mySampleClass;
   myMethodDelegate^ myD1 = gcnew myMethodDelegate( mySC, &mySampleClass::myStringMethod );
   myMethodDelegate^ myD2 = gcnew myMethodDelegate( mySampleClass::mySignMethod );
   
   // Invokes the delegates.
   Console::WriteLine( "{0} is {1}; use the sign \"{2}\".", 5, myD1( 5 ), myD2( 5 ) );
   Console::WriteLine( "{0} is {1}; use the sign \"{2}\".",  -3, myD1(  -3 ), myD2(  -3 ) );
   Console::WriteLine( "{0} is {1}; use the sign \"{2}\".", 0, myD1( 0 ), myD2( 0 ) );
}

/*
This code produces the following output:

5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/
import System.*;

public class SamplesDelegate
{
    /** @delegate 
     */
    // Declares a delegate for a method that takes in an int and returns
    // a String.
    public delegate String MyMethodDelegate(int myInt);

    // Defines some methods to which the delegate can point.
    public static class MySampleClass
    {
        // Defines an instance method.
        public String MyStringMethod(int myInt)
        {
            if (myInt > 0)  {
                return "positive";
            }
            if (myInt < 0) {
                return "negative";
            }
            return "zero";
        } //myStringMethod

        // Defines a static method.
        public static String MySignMethod(int myInt)
        {
            if (myInt > 0) {
                return "+";
            }
            if (myInt < 0) {
                return "-";
            }
            return "";
        } //MySignMethod
    } //MySampleClass

    public static void main(String[] args)
    {
        // Creates one delegate for each method.
        MySampleClass mySC = new MySampleClass();
        MyMethodDelegate myD1 = new MyMethodDelegate(mySC.MyStringMethod);
        MyMethodDelegate myD2 = new MyMethodDelegate(MySampleClass.MySignMethod);
        // Invokes the delegates.
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 
            (Int32)(5), System.Convert.ToString(myD1.Invoke(5)), 
            System.Convert.ToString(myD2.Invoke(5)));
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".",
            System.Convert.ToString(-3), System.Convert.ToString(myD1.Invoke(-3)),
            System.Convert.ToString(myD2.Invoke(-3)));
        Console.WriteLine("{0} is {1}; use the sign \"{2}\".", (Int32)(0),
            System.Convert.ToString(myD1.Invoke(0)), System.Convert.ToString(
            myD2.Invoke(0)));
    } //main
} //SamplesDelegate 

/*
This code produces the following output:
 
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/

继承层次结构

System.Object
  System.Delegate
     System.MulticastDelegate

线程安全

此类型的任何公共静态(Visual Basic 中的 Shared)成员都是线程安全的,但不保证所有实例成员都是线程安全的。

平台

Windows 98、Windows 2000 SP4、Windows CE、Windows Millennium Edition、Windows Mobile for Pocket PC、Windows Mobile for Smartphone、Windows Server 2003、Windows XP Media Center Edition、Windows XP Professional x64 Edition、Windows XP SP2、Windows XP Starter Edition

.NET Framework 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求

版本信息

.NET Framework

受以下版本支持:2.0、1.1、1.0

.NET Compact Framework

受以下版本支持:2.0、1.0

请参见

参考

Delegate 成员
System 命名空间
MulticastDelegate

其他资源

使用异步方式调用同步方法