我有一个抽象类A,它具有检查阈值所需的功能。当违反阈值时,我想要提出一个事件通知我。我在Qt中做过很多次这样的事情,但我似乎无法弄清楚如何将它转移到C#。这是我目前想到的结构。
namespace N
{
abstract class A
{
public delegate void Notify();
public event Notify Notifier;
public abstract void CheckThreshold();
}
class B : A
{
public override void CheckThreshold()
{
Notifier();
}
}
class N
{
public AlertMe()
{
}
public static Main()
{
var b = new B();
b.Notifier += new A.Notify(AlertMe);
b.CheckThreshold();
}
}
}
答案 0 :(得分:1)
您可以在基类A
中定义辅助方法protected void FireNotification()
{
if (Notifier != null)
Notifier();
}
并从被覆盖的CheckTreshold
调用此内容。
答案 1 :(得分:1)
通常,您要关注的表单是:
public event EventHandler<SomeEventArgs> SomeEvent = (s, e) => { };
protected virtual void OnSomeEvent(SomeEventArgs e)
{
SomeEvent(this, e);
}
所以在你的情况下你可能想要:
abstract class A {
public event EventHandler<EventArgs> ThresholdExceeded = (s, e) => { };
protected virtual void OnThresholdExceeded(EventArgs e)
{
ThresholdExceeded(e);
}
public abstract void CheckThreshold();
}
class B : A {
public override void CheckThreshold()
{
if (/* your condition */) OnThresholdExceeded(new EventArgs());
}
}
现在有一些事情--EventHandler类型是一个很好的语法糖,用于制作特定类型的事件。右边的lambda表达式将它初始化为默认处理程序,因此在调用它之前不必将其检查为null。
EventArgs是特定于事件的信息 - 您没有,但如果您这样做,您将继承EventArgs并输入您的事件接收器所需的任何数据。
Microsoft为.NET中的事件规定了public event SomeEventName
和protected virtual void OnSomeEvent
对的模式。你没有拥有来遵循这一点,但这是.NET程序员想要的。
答案 2 :(得分:1)
此代码存在多个问题。
首先,您应该使用EventHandler内置委托来定义事件。其次,你不能在定义它的类之外引发一个事件(这就是为什么你不能使用后代的Notify())。第三,你可以使用Template Method Design Pattern并更清楚地定义你的基类和它后代之间的契约,并实现threashold检查的一部分。
最后我根本不明白为什么你需要继承层次结构呢?也许你可以在一个类中实现所有必需的逻辑?但无论如何这里的代码将编译和行为正确:
abstract class A
{
// Avoid defining custom delegate at all because there is a lot of
// build-in events for every case, like EventHandler<T>,
// Func<T>, Action<T> etc
// public delegate void Notify();
public event EventHandler ThreasholdViolated;
protected void OnThreasholdViolated()
{
var handler = ThreasholdViolated;
if (handler != null)
handler(this, EventArgs.Empty);
}
public abstract void CheckThreshold();
}
class B : A
{
public override void CheckThreshold()
{
OnThreasholdViolated();
}
}
答案 3 :(得分:0)
通常的模式是在基类中提供受保护的虚方法,如http://msdn.microsoft.com/en-us/library/vstudio/9aackb16(v=vs.100).aspx所示。该方法名称的约定是On [EventName]并接受事件args实例。
还遵循使用EventHandler或EventHandler作为委托的约定,并提供事件发起者和相应的参数。您可以在http://msdn.microsoft.com/en-us/library/vstudio/ms229011(v=vs.100).aspx中找到有关此内容的更多信息。请注意,来自MSDN的示例不遵循所有这些约定。
答案 4 :(得分:-1)
public abstract class A
{
public EventHandler<EventArgs> OnThresholdViolated;
public abstract void CheckThreshold();
}
public class B : A
{
public B(EventHandler<EventArgs> alertMe) {
OnThresholdViolated += alertMe;
}
public override void CheckThreshold()
{
if (null != OnThresholdViolated)
{
OnThresholdViolated(this, EventArgs.Empty);
}
}
}
然后使用:
打电话 B b = new B(AlertMe);
b.CheckThreshold();