首页 > 编程 > C# > 正文

C#中的委托和事件学习(续)

2020-04-24 22:01:40
字体:
来源:转载
供稿:网友

引言

如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识。但那些远不是委托和事件的全部内容,还有很多的地方没有涉及。本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器、异常处理、超时处理和异步方法调用等内容。

为什么要使用事件而不是委托变量?

在 C#中的委托和事件 中,我提出了两个为什么在类型中使用事件向外部提供方法注册,而不是直接使用委托变量的原因。主要是从封装性和易用性上去考虑,但是还漏掉了一点,事件应该由事件发布者触发,而不应该由客户端(客户程序)来触发。这句话是什么意思呢?请看下面的范例:

NOTE:注意这里术语的变化,当我们单独谈论事件,我们说发布者(publisher)、订阅者(subscriber)、客户端(client)。当我们讨论Observer模式,我们说主题(subject)和观察者(observer)。客户端通常是包含Main()方法的Program类。

class Program {   static void Main(string[] args) {     Publishser pub = new Publishser();     Subscriber sub = new Subscriber();          pub.NumberChanged += new NumberChangedEventHandler(sub.OnNumberChanged);     pub.DoSomething();     // 应该通过DoSomething()来触发事件    pub.NumberChanged(100);   // 但可以被这样直接调用,对委托变量的不恰当使用  } }// 定义委托public delegate void NumberChangedEventHandler(int count);// 定义事件发布者public class Publishser {   private int count;   public NumberChangedEventHandler NumberChanged;     // 声明委托变量  //public event NumberChangedEventHandler NumberChanged; // 声明一个事件  public void DoSomething() {     // 在这里完成一些工作 ...     if (NumberChanged != null) {  // 触发事件      count++;       NumberChanged(count);     }   } }// 定义事件订阅者public class Subscriber {   public void OnNumberChanged(int count) {     Console.WriteLine("Subscriber notified: count = {0}", count);   } }

上面代码定义了一个NumberChangedEventHandler委托,然后我们创建了事件的发布者Publisher和订阅者Subscriber。当使用委托变量时,客户端可以直接通过委托变量触发事件,也就是直接调用pub.NumberChanged(100),这将会影响到所有注册了该委托的订阅者。而事件的本意应该为在事件发布者在其本身的某个行为中触发,比如说在方法DoSomething()中满足某个条件后触发。通过添加event关键字来发布事件,事件发布者的封装性会更好,事件仅仅是供其他类型订阅,而客户端不能直接触发事件(语句pub.NumberChanged(100)无法通过编译),事件只能在事件发布者Publisher类的内部触发(比如在方法pub.DoSomething()中),换言之,就是NumberChanged(100)语句只能在Publisher内部被调用。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表