触发器 - 事件或委托事件 [英] Trigger - Event or delegate with event

查看:75
本文介绍了触发器 - 事件或委托事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,

推荐答案

如果您需要通知该类型外部的用户,请使用事件。请注意,委托和事件不是排他性的。事实上,代表们的活动是如何运作的。 Delegate是一个函数对象(其他语言的函子),是你用
挂钩事件处理程序的东西。

If you need to notify users external to the type about something then use an event. Note that delegates and events are not exclusive things. In fact delegates are how events work. Delegate is a function object (functor in other languages) and is what you use to hook up event handlers.

我怀疑你正在考虑一个不同的回调(也使用委托)。当代码需要调用函数才能工作时,会使用回调。在决定回调与事件时,我认为有几件事情很重要 - 听众的数量
和责任。事件可以包含任何数量的侦听器,包括0.回调可以有1(如果是可选的话,则为0)。

I suspect you are thinking of a callback (which also uses delegates) which is different. A callback is used when code needs to call a function in order to work. There are a couple things that I think are important when deciding callback vs event - # of listeners and responsibility. Events can have any # of listeners, including 0. Callbacks can have 1 (or 0 if it is optional).


  •  事件(通知模型)
  •     可能有超过一名听众
  •     没有听众不会以任何方式更改主叫代码 
  •  回调(互动模式)
  •      0或1名听众
  •     
  •  不支持或明确编码没有听众。   监听器在调用代码中扮演不可或缺的角色(例如做出决定)

例如,在绘图程序中更改当前选择的对象可能需要"属性"。要更新的窗口,要刷新的UI以及可能要更改的状态栏。由于代码不知道谁想要被通知以及他们将以b $ b做什么,因此事件是合适的。

As an example, changing the currently selected object in a drawing program may require a "properties" window to be updated, the UI to refresh and perhaps the status bar to change. Since the code doesn't know who wants to be notified and what they'll do an event is appropriate.

class SelectionManager
{
   public DrawObject Selected { get; }
   
   public event EventHandler SelectionChanged;
}

class PropertyWindow
{
   void Initialize ( SelectionManager manager )
   {
      manager.SelectionChanged += UpdateUI;
   }

   void UpdateUI ( object sender, EventArgs e )
   {      
   }
}

class StatusBar
{
   void Initialize ( SelectionManager manager )
   {
      manager.SelectionChanged += UpdateUI;
   }

   void UpdateUI ( object sender, EventArgs e )
   {      
   }
}

但是如果你想实现一个访问模式来枚举桌面上的窗口,那么回调就更合适了。这是一次性的事情(在枚举过程中),只有调用代码才会关心。

But if you want to implement a visitor pattern where you enumerate the windows on the desktop then a callback is more appropriate. It is a one time thing (during the course of the enumeration) and only the calling code will care.

public delegate bool EnumWindowsDelegate ( IntPtr window );

class WindowEnumerator
{   
   public void EnumerateWindows ( EnumWindowsDelegate callback )
   {
      //Get next window
      var window = …;

      //Notify callback
      callback(window);
   }
}

在示例代码中,EventHandlerContentSentBack看起来像一个回调。事件始终具有EventArgs的第二个参数(或从其派生的类型)。因此,定义该委托然后将其作为事件公开是不合适的。做一个或另一个。我认为
事件在这里是合适的,因为处理程序对事件做出反应,而不是事件的组成部分。其他人也可能感兴趣。这是发生事情的通知。

In your sample code EventHandlerContentSentBack looks like a callback. Events always have a second parameter of EventArgs (or a type derived from it). So it is inappropriate to define that delegate and then expose it as an event. Do one or the other. I think an event is appropriate here because the handler is reacting to the event, not an integral part of it. Others may be interested as well. It is a notification that something occurred.

class ContentSentBackEventArgs : EventArgs
{
   public ContentSentBackEventArgs ( string value )
   {
      Content = value;
   }

   public string Content { get; private set; }
}

class RS232
{
   public event EventHandler<ContentSentBackEventArgs> EvHaContentSentBack;

   public event EventHandler ThresholdReached;
}

//Consumer
class MyClass
{   
   public void Initialize ( RS232 rs232 )
   {
      rs232.EvHaContentSentBack += OnContentSentBack;
   }

   private void OnContentSentBack ( object sender, ContentSentBackEventArgs e )
   {
      Dispatcher.Invoke((Action)(() => {
         txtSentBack.Text += e.Content;
         txtSentBack.Focus();
         ...
      });
   }
}


这篇关于触发器 - 事件或委托事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆