在典型的事件设计中,您有一个带有受保护的虚拟事件提升者的公共事件。但是,在我的项目中,我有一个主要类,它基本上充当其他几个类的管理器。有什么理由我不应该像这样设置课程,这样客户只需要订阅经理课程的事件而没有别的吗? (注意:这是根据我的实际代码键入的袖口,因此请原谅任何可能的轻微编码错误。)
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.");
}
}
答案 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
值或XClass
和YClass
,那么我将不会太高兴。想象一下,您已订阅了Button
点击事件并投了sender as Button
但由于发件人为Employee
而失败...
这就是为什么惯例是创建一个受保护的OnEvent
,例如OnClick
或OnPaint
,并允许派生类将EventArgs
传递给它。< / p>
答案 2 :(得分:0)
从技术上讲,你可以做到这一点,但在我看来,这是一个糟糕的设计选择。事件应该通知外部订阅者在您的类的对象内发生的事情。因此,只有定义事件的类必须知道并决定何时引发事件。