是否有理由不参加公共/内部活动?

时间:2016-12-25 19:41:54

标签: c# events

在典型的事件设计中,您有一个带有受保护的虚拟事件提升者的公共事件。但是,在我的项目中,我有一个主要类,它基本上充当其他几个类的管理器。有什么理由我不应该像这样设置课程,这样客户只需要订阅经理课程的事件而没有别的吗? (注意:这是根据我的实际代码键入的袖口,因此请原谅任何可能的轻微编码错误。)

public class Manager
{
    public event EventHandler<WarningEventArgs> Warning;

    // Could also be internal or protected internal
    // Updated based on comments below.
    public void RaiseWarning(IMessageSource sender, string warning)
    {
        // this.Warning?.Invoke(sender, new WarningEventArgs(warning);
        this.Warning?.Invoke(this, new WarningEventArgs(sender, warning);
    }
}

public class Managed
{
    public Managed(Manager manager)
    {
        this.Manager = manager;
    }

    public Manager Manager { get; }

    public void JustSoYouKnow()
    {
        this.Manager.RaiseWarning(this, "Something happened you should know about.");
    }
}

3 个答案:

答案 0 :(得分:1)

我认为,这种模式可以存在,只需稍加修改:

public class Manager: IMessenger, IMessageSender
{
   public event EventHandler<WarningEventArgs> Warning;

   // Could also be internal or protected internal
   public void RaiseWarning(object sender, string warning)
   {
      this.Warning?.Invoke(sender, new WarningEventArgs(warning);
   }
}

public interface IMessenger{
    event EventHandler<WarningEventArgs> Warning;
}    

public interface IMessageSender
{
    void RaiseWarning(object sender, string warning);
}

在这种情况下,您可以将您的类作为IMessenger提供给接收者,将IMessageSender提供给消息生成器。在这种情况下,Manager扮演消息传递者的角色,而不是(并且不应该)彼此了解的类。

答案 1 :(得分:1)

没有那种设计毫无意义。想象一下:

Manager mgr = new Manager();

// What if I do this?
mgr.RaiseWarning(null, "Something happened");

现在,您的Manager课程将通知每个订阅者“发生了什么事”。所以任何使用你的课程的人都可以触发这个,那又有什么意义呢?

如果我们按照您的方法进行成像,则会构建一个BadButton,其中包含Click事件。即使没有发生点击,任何人都可以调用Click方法。

我可以将它们内部制作吗?

如果你把它作为内部,取决于来电者,他们仍然可以传递任何他们想要的sender。如果我正在使用您的Manager课程并且我订阅了该活动,我希望sender属于Manager类型。如果您让其他课程执行此操作并且您向我发送null值或XClassYClass,那么我将不会太高兴。想象一下,您已订阅了Button点击事件并投了sender as Button但由于发件人为Employee而失败...

这就是为什么惯例是创建一个受保护的OnEvent,例如OnClickOnPaint,并允许派生类将EventArgs传递给它。< / p>

答案 2 :(得分:0)

从技术上讲,你可以做到这一点,但在我看来,这是一个糟糕的设计选择。事件应该通知外部订阅者在您的类的对象内发生的事情。因此,只有定义事件的类必须知道并决定何时引发事件。