Modern C# 系列课程笔记 第11节 深入委托和事件

一)委托的概念及定义 

 A delegate declaration defines a reference type that can be used to encapsulate a method with a specific signature. A delegate instance  encapsulates a static or an instance method. Delegates are roughly similar to function pointers in C++; however,delegates are type-safe and secure. 

——MSDN

C# delegate is a callback function. It is smarter then standard” callback because it allows defining a strict list of parameters which are passed from class-server to class-client. 

——CodeProject 

委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。

(思考  委托能够分配方法:创建一个委托实例,然后将方法付给委托的实例。委托将与该方法具有完全相同的行为:用委托代理方法的时候,给托做什么是由方法决定的。)

——C# 编程指南

 

二)委托与C++函数指针区别 ——Stanley B.Lippman

一个delegate object 一次可以搭载多个方法,而不是一次一个。当我们唤起一个搭载了多个方法的delegate,所有方法以其“被搭载到delegate object 的顺序”被依次唤起                                 

     一个delegate object 所搭载的方法并不需要属于同一个类。一个delegate object 所搭载的所有方法必须具有相同的原型和形式。然而,这些方法可以即有static 也有non-static,可以由一个或多个不同类的成员组成。                                                 

     一个delegate type 的声明在本质上是创建了一个新的subtype instance,该subtype 派生自.NET library framework abstract base classes Delegate MulticastDelegate,它们提供一组public methods 用以询访delegate object 或其搭载的方法。

 

三)对委托的个人理解 

委托是函数的封装,它代表一“类”函数。它们都符合一定的签名:拥有相同的参数列表、返回值类型。同时,委托也可以看成是对函数的抽象,是函数的“类”。此时,委托的实例将代表一个具体的函数。

 

四)委托和接口的区别?

接口:对于方法的抽象,定义了方法的原型

 

五)为什么使用委托?

5.1)更加灵活的方法调用。

例如:指定不同的排序方法,可以得到不同的排序结果。排序方法的签名是一样的。

5.2)用于异步回调。

5.3)多线程编程中使用委托来指定启动一个线程时调用的方法。

5.4C# 中的事件模型。用它们指明处理给定事件的方法。

 

六)如何使用委托 

 

   <modifiers> delegate <return_type> <delegate_name> ( argument_list )  

   public delegate void Del(string message); 

 

   public void DelegateMethod(string message) //Class DelClass 

   { 

System.Console.WriteLine(message); 

}  

 

   Del handler = new Del (obj.DelegateMethod);  

   handler("Hello World");  

 

先声明委托,再实例化并指明所代具体方法 

 

七)委托应用——异步回调 

异步回调:由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性。这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托。这称为异步回调,是在较长的进程完成后用来通知调用方的常用方法。以这种方式使用委托时,使用委托的代码无需了解有关所用方法的实现方面的任何信息。

 

// callback 是一个委托的实例

public void MethodWithCallback(int param1, int param2, Del callback ) {  

callback("The number is: " + (param1 + param2).ToString()); 

 

// 在此调用

MethodWithCallback(1, 2, handler);  

 

回调的另一个常见用法是:定义自定义的比较方法并将该委托传递给排序方法。

解释:

 

委托实现回调类似于接口所实现的封装?  

 

八)何时委托?何时接口? 

 

在以下情况中使用委托:  

      1)当使用事件设计模式时。  

      2)当封装静态方法可取时。  

      3)当调用方不需要访问实现该方法的对象中的其他属性、 方法或接口时。 

      4)需要方便的组合。 

    例如:将开门、上楼梯、进门一系列的动作组合到一起。

      5)当类可能需要该方法的多个实现时。

    例如:不同的实现,相同的原型。

 

在以下情况中使用接口:  

      1)当存在一组可能被调用的相关方法时。 

      2)当类只需要方法的单个实现时。注:多个实现用委托

      3)当使用接口的类想要将该接口强制转换为其他接口或类类型时。 

 

九)多播委托 

     多播委托——引用多个方法的委托,它连续调用每个方法。委托必须是同类型的,返回类型必须是void,不能带输出参数(可以带引用参数)。多播委托应用于事件模型中。 

 

   public class DelClass {  

         public void Method1(string message) { } 

         public void Method2(string message) { } 

   }

   DelClass obj = new DelClass(); 

   Del d1 = obj.Method1; 

   Del d2 = obj.Method2; 

   Del d3 = obj.DelegateMethod; 

   Del allMethodsDelegate = d1 + d2; 

   allMethodsDelegate += d3; 

 

十)牛奶+报纸实例分析

 

1)为什么牛奶箱不能投递报纸? 

2)使用委托让牛奶报纸共享箱子 

 

十一)委托在多线程编程的应用

  皮特的故事  参考:http://blog.csdn.net/uoyevoli/archive/2005/09/02/469963.aspx

 

注: 参考代码

原文地址:https://www.cnblogs.com/lujiao_cs/p/2076860.html