A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate. The following example declares a delegate named Del that can encapsulate a method that takes a string as an argument and returns void:
委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似。 与 C 中的函数指针不同,委托是面向对象的、类型安全的和保险的。 委托的类型由委托的名称定义。 下面的示例声明了一个名为 Del 的委托,该委托可以封装一个采用字符串作为参数并返回 void 的方法。)
public delegate void Del(string message);
A delegate object is normally constructed by providing the name of the method the delegate will wrap, or with an anonymous Method. Once a delegate is 
instantiated, a method call made to the delegate will be passed by the delegate to that method. The parameters passed to the delegate by the caller are passed to the method, and the return value, if any, from the method is returned to the caller by the delegate. This is known as invoking the delegate. An instantiated delegate can be invoked as if it were the wrapped method itself. For example:
(构造委托对象时,通常提供委托将包装的方法的名称或使用匿名方法。 实例化委托后,委托将把对它进行的方法调用传递给方法。 调用方传递给委托的参数被传递给方法,来自方法的返回值(如果有)由委托返回给调用方。 这被称为调用委托。 可以将一个实例化的委托视为被包装的方法本身来调用该委托。 例如:)
// 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");
Delegate types are derived from the Delegate class in the .NET Framework. Delegate types are sealed—they cannot be derived from— and it is not possible to derive custom classes from Delegate. Because the instantiated delegate is an object, it can be passed as a parameter, or assigned to a property. This allows a method to accept a delegate as a parameter, and call the delegate at some later time. This is known as an asynchronous callback, and is a common method of notifying a caller when a long process has completed. When a delegate is used in this fashion, the code using the delegate does not need any knowledge of the implementation of the method being used. The functionality is similar to the encapsulation interfaces provide. For more information, see When to Use Delegates Instead of Interfaces.
Another common use of callbacks is defining a custom comparison method and passing that delegate to a sort method. It allows the caller's code to become part of the sort algorithm. The following example method uses the Del type as a parameter:
(委托类型派生自 .NET Framework 中的 Delegate 类。 委托类型是密封的,不能从 Delegate 中派生委托类型,也不可能从中派生自定义类。 由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性。 这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托。 这称为异步回调,是在较长的进程完成后用来通知调用方的常用方法。 以这种方式使用委托时,使用委托的代码无需了解有关所用方法的实现方面的任何信息。 此功能类似于接口所提供的封装。 有关更多信息,请参见何时使用委托而不使用接口。
回调的另一个常见用法是定义自定义的比较方法并将该委托传递给排序方法。 它允许调用方的代码成为排序算法的一部分。 下面的示例方法使用 Del 类型作为参数:)
public void MethodWithCallback(int param1, int param2, Del callback)
{
callback("The number is: " + (param1 + param2).ToString());
}
MethodWithCallback(, , handler);//(PS:注意回调这种用法)

-----------------------分割线-------------------------------------

When a delegate is constructed to wrap an instance method, the delegate references both the instance and the method. A delegate has no knowledge of the instance type aside from the method it wraps, so a delegate can refer to any type of object as long as there is a method on that object that matches the delegate signature. When a delegate is constructed to wrap a static method, it only references the method. Consider the following declarations:
(将委托构造为包装实例方法时,该委托将同时引用实例和方法。 除了它所包装的方法外,委托不了解实例类型,所以只要任意类型的对象中具有与委托签名相匹配的方法,委托就可以引用该对象。 将委托构造为包装静态方法时,它只引用方法。 考虑下列声明:)
public class MethodClass
{
public void Method1(string message) { }
public void Method2(string message) { }
}
Along with the static DelegateMethod shown previously, we now have three methods that can be wrapped by a Del instance.
A delegate can call more than one method when invoked. This is referred to as multicasting. To add an extra method to the delegate's list of methods—the invocation list—simply requires adding two delegates using the addition or addition assignment operators ('+' or '+='). For example:
(加上前面显示的静态 DelegateMethod,现在我们有三个方法可由 Del 实例进行包装。
调用委托时,它可以调用多个方法。 这称为多路广播。 若要向委托的方法列表(调用列表)中添加额外的方法,只需使用加法运算符或加法赋值运算符(“+”或“+=”)添加两个委托。 例如:)
MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod; //Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;
At this point allMethodsDelegate contains three methods in its invocation list—Method1, Method2, and DelegateMethod. The original three delegates, d1, d2, 
and d3, remain unchanged. When allMethodsDelegate is invoked, all three methods are called in order. If the delegate uses reference parameters, the reference is passed sequentially to each of the three methods in turn, and any changes by one method are visible to the next method. When any of the methods throws an exception that is not caught within the method, that exception is passed to the caller of the delegate and no subsequent methods in the invocation list are called. If the delegate has a return value and/or out parameters, it returns the return value and parameters of the last method invoked. To remove a method from the invocation list, use the decrement or decrement assignment operator ('-' or '-='). For example:
(此时,allMethodsDelegate 在其调用列表中包含三个方法 -- Method1、Method2 和 DelegateMethod。 原来的三个委托 d1、d2 和 d3 保持不变。 调用 allMethodsDelegate 时,将按顺序调用所有这三个方法。 如果委托使用引用参数,则引用将依次传递给三个方法中的每个方法,由一个方法引起的更改对下一个方法是可见的。 如果任一方法引发了异常,而在该方法内未捕获该异常,则该异常将传递给委托的调用方,并且不再对调用列表中后面的方法进行调用。 如果委托具有返回值和/或输出参数,它将返回最后调用的方法的返回值和参数。 若要从调用列表中移除方法,请使用减法运算符或减法赋值运算符(“-”或“-=”)。 例如:
//remove Method1
allMethodsDelegate -= d1; // copy AllMethodsDelegate while removing d2
Del oneMethodDelegate = allMethodsDelegate - d2;
Because delegate types are derived from System.Delegate, the methods and properties defined by that class can be called on the delegate. For example, to find the number of methods in a delegate's invocation list, you may write:
(由于委托类型派生自 System.Delegate,所以可在委托上调用该类定义的方法和属性。 例如,为了找出委托的调用列表中的方法数,您可以编写下面的代码:)
int invocationCount = d1.GetInvocationList().GetLength();
Delegates with more than one method in their invocation list derive from MulticastDelegate, which is a subclass of System.Delegate. The above code works in either 
case because both classes support GetInvocationList.
Multicast delegates are used extensively in event handling. Event source objects send event notifications to recipient objects that have registered to receive that
event. To register for an event, the recipient creates a method designed to handle the event, then creates a delegate for that method and passes the delegate to the event source. The source calls the delegate when the event occurs. The delegate then calls the event handling method on the recipient, delivering the event data. The delegate type for a given event is defined by the event source. For more, see Events (C# Programming Guide).
Comparing delegates of two different types assigned at compile-time will result in a compilation error. If the delegate instances are statically of the type System.
Delegate, then the comparison is allowed, but will return false at run time. For example:
(在调用列表中具有多个方法的委托派生自 MulticastDelegate,这是 System.Delegate 的子类。 由于两个类都支持 GetInvocationList,所以上面的代码在两种情况下都适用。
多路广播委托广泛用于事件处理中。 事件源对象向已注册接收该事件的接收方对象发送事件通知。 为了为事件注册,接收方创建了旨在处理事件的方法,然后为该方法创建委托并将该委托传递给事件源。 事件发生时,源将调用委托。 然后,委托调用接收方的事件处理方法并传送事件数据。 给定事件的委托类型由事件源定义。 有关更多信息,请参见事件(C# 编程指南)。
在编译时,对分配了两种不同类型的委托进行比较将产生编译错误。 如果委托实例静态地属于类型 System.Delegate,则允许进行比较,但在运行时将返回 false。 例如:)
delegate void Delegate1();
delegate void Delegate2(); static void method(Delegate1 d, Delegate2 e, System.Delegate f)
{
// Compile-time error.
//Console.WriteLine(d == e); // OK at compile-time. False if the run-time type of f
// is not the same as that of d.
System.Console.WriteLine(d == f);
}

c# 关键字delegate、event(委托与事件)[MSDN原文摘录][1]的更多相关文章

  1. Delegate(委托与事件)

    Delegate可以当它是一个占位符,比如你在写代码的时候并不知道你将要处理的是什么.你只需要知道你将要引入的参数类型和输出类型是什么并定义它即可.这就是书本上所传达的方法签名必须相同的意思. 系统自 ...

  2. c# 关键字delegate、event(委托与事件)[MSDN原文摘录][2]

    //Demo1:Declaring an event in an interface and implementing it in //a class. // event_keyword.cs usi ...

  3. Delegate event 委托事件---两个From窗体使用委托事件

    窗体如下:   public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void b ...

  4. 委托与事件--delegate&&event

    委托 访问修饰符 delegate 返回值 委托名(参数); public delegate void NoReturnNoPara(); public void NoReturnNoParaMeth ...

  5. 浅谈C#委托和事件

    委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...

  6. 浅谈C#委托和事件【转】

    委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...

  7. 浅谈C#委托和事件(转载)

    委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...

  8. C#基础加强(8)之委托和事件

    委托 简介 委托是一种可以声明出指向方法的变量的数据类型. 声明委托的方式 格式: delegate <返回值类型> 委托类型名(参数) ,例如: delegate void MyDel( ...

  9. C#语法之委托和事件

    从大学就开始做C#这块,也做C#几年了,最近又从ios转回.Net,继续做C#,之前也没有写博客的习惯,写博客也是从我做ios的时候开始的,现在既然又做回了.net,那就写点关于.Net的博客,可能在 ...

随机推荐

  1. hdu 1568 Fibonacci 快速幂

    Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Proble ...

  2. Codeforces Round #288 (Div. 2) C. Anya and Ghosts 模拟

    C. Anya and Ghosts time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. Yii 如何渲染另一控制器中的视图。

    (Yii)使用renderPartial调用另外一个控制器的视图 我们可以使用renderPartial访问存储在不同控制器的视图文件夹中的部分视图文件. 在Yii1.1.3中,我们使用双斜线“//” ...

  4. Scrum Meeting---Eleven(2015-11-6)

    今日已完成任务和明日要做的任务 姓名 今日已完成任务 今日时间 明日计划完成任务 估计用时 董元财 倒计时设计 3h 商品发布页设计 4h 胡亚坤 低栏设计 2h UI风格 2h 刘猛 通讯录设计 2 ...

  5. iOS - OC NSFileManager 文件管理

    前言 @interface NSFileManager : NSObject @interface NSFileHandle : NSObject <NSSecureCoding> NSF ...

  6. iOS - Swift Swift 语言新特性

    1.Swift 2.0 带来哪些新变化 常规变化: 1.OS X 10.11.iOS 9 和 watchOS 2 SDK 采纳了一些 Objective-C 的特性用来提高 Swift 的编程体验, ...

  7. poj1673EXOCENTER OF A TRIANGLE

    链接 据说这题是垂心..数学太弱没有看出来,写了分朴实无华的代码.. 旋转三边得到图中的外顶点,然后连接三角形顶点求交点,交上WA..觉得没什么错误就去看了下discuss,发现都在说精度问题,果断开 ...

  8. c++中的类的对象与类的指针

    以上内容来自:http://wenku.baidu.com/link?url=haeRBhswlEcqddk48uW8YVMsdFNWsllimn_dzUYchb6G9NdT4pqgluCpnLQId ...

  9. MATLAB中的nargin与varargin的用法

    nargin的用法: nargin:number of function input arguments,指的是一个函数的输入变量的个数. 用法:nargin或着nargin(fx), 其中fx指的是 ...

  10. iOS开发之 在release版本禁止输出NSLog内容

    因为NSLog的输出还是比较消耗系统资源的,而且输出的数据也可能会暴露出App里的保密数据,所以发布正式版时需要把这些输出全部屏蔽掉. 我们可以在发布版本前先把所有NSLog语句注释掉,等以后要调试时 ...