介绍如何使用C#中的委托

看到一篇很不错的文章 转了

代表使得这样的方案变为可能:其他语言-C++, Pascal, Modula 等可以用功能指针来定位。与C++的功能指针不同,代表完全是面向对象的;与C++指向成员功能不同,代表把一个对象实例和方法都进行封装。

一个代表声明定义了一个从类System.Delegate 延伸的类。一个代表实例封装一个方法,可调用实体。对于实例方法,一个可调用实体由一个实例和一个实例中的方法组成。对于静态方法,一个可调用实体完全只是由一个方法组成。如果你有一个代表实例和一个适当的参数集合,你就可以用参数来调用这个代表。

代表的一个有趣而又有用的特性是它不知道或不关心它引用的对象的类。只要方法的签名与代表的签名一致,任何对象都可以作。这使得代表适合作“匿名“调用”。

1.1 代表声明

一个代表声明( delegate-declaration )是一个类型声明(type-declaration 9.5) ,它声明一个新的代表类型。

delegate-declaration:
attributesopt   delegate-modifiersopt  
delegate   result-type   identifier   (   formal-parameter-listopt   )   ;

delegate-modifiers:
delegate-modifier
delegate-modifiers   delegate-modifier

delegate-modifier:
new
public
protected
internal

private

在代表声明中相同的修饰符出现多次是错误的。

new 修饰符只允许在被其他类型声明代表中出现。它指定那个代表用相同的名称隐藏一个继承的成员,就像在§10.2.2中描述的一样。

public, protected, internal, private 修饰符控制代表类型的访问能力。根据代表声明发生的上下文,这些修饰符中的某些将不被允许错误!未找到引用源。)

形式参数列表指定了代表的签名,而结果类型(result-type )指定了代表的返回类型。代表的签名和返回类型必须与代表类型所包装的方法的签名和返回类型匹配。C#中的代表类型是名称等价的,并不是结构上等价。两个有相同签名和返回类型的不同的代表类型被认为是不同的代表类型。

一个代表类型是一个从System.Delegate 派生的类类型。代表类型隐含为密封的:从代表类型派生任何类型是不行的。从System.Delegate 派生一个非代表类型的类也不被允许。注意,System.Delegate 自己不是一个代表类型,它是一个类类型,而所有代表类型都从它派生。

C# 为代表实例化和调用提供了特别的语法。除了实例化,可以用于类或类的实例的任何操作也都可以被用于代表类或实例。特别是,通过使用成员访问语法可以访问System.Delegate 类型的成员。

1.1.1 可合并的代表类型

代表类型被分为两类:可合并的和不可合并得。一个可合并的代表类型必须满足下面的条件:

·         代表类型声明的返回类型必须是void

·         代表类型的参数都不能作为输出参数10.5.1.3)来声明。

如果试图合并错误!未找到引用源。)两个不可合并代表类型的实例,就会发生一个运行时的异常,除非一个或另一个实例为null

1.2 代表实例化

虽然代表的行为在大多数情况下与其他的类相似, C# 还是为实例化一个代表实例提供了特殊的语法。一个代表创建表达式(delegate-creation-expression 7.5.10.3) 用来创建一个代表的新实例。最新创建的代表实例就会指向下面之一:

·         在实例创建表达式(delegate-creation-expression引用的方法,或是

·         目标对象(不能为null)和在实例创建表达式(delegate-creation-expression引用的实例方法,或

·         另一个代表

一旦被实例化,代表实例通常指向相同的目标对象和方法。

1.3 多点传送代表

代表可以使用加操作符错误!未找到引用源。)来合并,并且一个代表可以通过使用减操作符来从另一个代表中去掉。一个通过合并两个或多个(非空)代表实例创建的代表实例被称为多点传送(multicast)代表实例。对于任何代表实例,代表实例的调用列表(invocation list )作为非多点传送的规则列表来定义,而当代表实例被调用时,它也要被调用。更多如下:

·         对于非多点传送代表实例,调用列表有代表实例自己组成。

·         对于通过把两个代表合并创建的多点传送代表实例,调用列表是通过使用创建多点传送代表的加法操作的两个操作数的调用列表合并得到的。

1.4 代表调用

C# 为调用一个代表提供特殊的语法。当一个非多嵌入代表被调用时,对代表用相同参数指向的方法进行调用,并且返回指向这个方法返回的相同数值。有关代表调用的详细信息参考§7.5.5.2。如果在一个代表的调用过程中出现了一个异常,并且这个异常没有在所调用的方法中被抓住,那么对异常俘获语句的搜索会扩展到的调用这个代表的方法中,就好像那个方法已经直接被代表指向的方法调用了一样。

多嵌入代表的调用通过按顺序调用在调用列表中的每个代表来进行。每个调用都会传送相同的参数集合。如果代表包含引用参数10.5.1.2),那么每个方法调用将引用相同的变量;通过某个调用列表中的方法对那个变量进行的改动会被调用列表中的后面的调用“看到”。

如果在多嵌入代表的调用过程中发生了一个异常,而这个异常没有被调用的方法俘获,那么对异常俘获语句的搜索会扩展到的调用这个代表的方法中,并且调用列表中任何后面的方法都不会被调用。

若标题中有“转载”字样,则本文版权归原作者所有。若无转载字样,本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
原文地址:https://www.cnblogs.com/mmbbflyer/p/1622112.html