使用事件“源”的嵌套对象指针是否正确?

时间:2012-03-13 13:28:19

标签: c# .net events event-handling

让我以一个例子来介绍这个问题:

我们有UserNotification类。它包含有关通知,可能的用户选项的信息。

public class UserNotification
{
    // Event fired on notification broadcast
    public event EventHandler<NotifyEventArgs> Notification;

    public string Title { get; set; }
    public string Description { get; set; }
    public List<NotificationResults> Options { get; set; }
    // ...

    // This function is called to raise notification 
    public void Notify()
    {
        if (Notification != null) Notification(null, new NotifyEventArgs());
    }
}

所以我们有一堆通知。每当程序的某些部分需要引发通知(对于用户)时,它需要一些通知对象并调用Notify()方法。然后触发Notification事件,所有侦听器都可以处理此通知(在gui中显示它,显示对话框等)。

最后,从软件的不同部分甚至插件中都会有这样的通知。并且通知听众很可能会喜欢将它们全部排除在外。因此,接下来要记住的是NotificationManager。它具有UserNotification和NotificationRaised事件的集合,当任何已注册的通知触发其Notification事件时会触发该事件

public class NotificationManager
{
    public event EventHandler NotificationRaised;

    private List<UserNotification> _notifications;

    public void AddNotification(UserNotification notification)
    {
        _notifications.Add(notification);
        notification.Notification += () => 
                  { 
                      if (NotificationRaised != null) NotificationRaised(???, ???) 
                  };
    }

这就是问题所在。看看 NotificationRaised(???,someEventArgs)。此时,我们需要将指针传递给源通知,以便侦听器可以使用此特定通知。 NotificationManager的事件处理程序有'source'字段,看起来与我们需要的完全相同......问题是:

将Notification指针作为源是否正确?或者通过设计和一些很好的理由来源必须是触发事件的对象?

换句话说,如果看一下这个例子,它会是“预期的行为”吗?

2 个答案:

答案 0 :(得分:1)

如果您要转发活动,我认为从原始活动转发来源没有问题。

答案 1 :(得分:1)

恕我直言,可以用新的东西替换发件人。我已经做过这个的最明显的例子是其他东西的代理对象。在那里,我订阅了真实班级的每个事件,并使用替换的发件人(代理本身)转发事件。

但也许对实施的这种改变会给你足够的未来自由:

public void AddNotification(UserNotification notification)
{
    AddNotification(notification, false);
}

public void AddNotification(UserNotification notification, bool useOriginalSender)
{
    _notifications.Add(notification);
    notification.Notification += (originalSender, e) =>
                {
                    var temp = NotificationRaised;

                    if (temp != null)
                    {
                        var sender = useOriginalSender ? originalSender : this;
                        temp(sender, NotifyEventArgs.Empty);
                    }
                };
}