详谈Delegate (一)

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

[SerializableAttribute] 
[ClassInterfaceAttribute(ClassInterfaceType.AutoDual)] 
[ComVisibleAttribute(true)] 
public abstract class Delegate : ICloneable, ISerializable

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

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

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

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

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

  • 静态方法。

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

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

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

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

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

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

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

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

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

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

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 ) );
   }

}


 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值