问题
I have event declared in abstract class:
public abstract class AbstractClass
{
public event Action ActionEvent;
}
public class MyClass : AbstractClass
{
private void SomeMethod()
{
//Want to access ActionEvent-- Not able to do so
if (ActionEvent != null)
{
}
}
}
I wanted to access this base class event in derived. Further I wanted to access this event in some other derived class of MyClass:
MyClass.ActionEvent += DerivedMethod()
Please help me understand how to work with event defined in abstract classes.
回答1:
This approach could be dangerous, see below for a better one
Events can only be raised (or checked for null apparently) from within the declaring class. This protection extends to derived classes.
Thus, the solution is to re-declare the event as an implementation of an abstract event in the base class. Then you can still use it via a base class reference as you want, and raise/use it in the derived class:
public abstract class AbstractClass
{
public abstract event Action ActionEvent;
}
public class MyClass : AbstractClass
{
public override event Action ActionEvent;
private void SomeMethod()
{
//Want to access ActionEvent-- Now you can!
if (ActionEvent != null)
{
}
}
}
Correct approach
MSDN Suggests that this approach may not be handled by the compiler correctly. Instead you should provide protected
methods so derived classes can check for null, invoke the event, etc:
public abstract class AbstractClass
{
public event Action ActionEvent;
protected bool EventIsNull()
{
return ActionEvent == null;
}
}
public class MyClass : AbstractClass
{
private void SomeMethod()
{
//Want to access ActionEvent-- Now you can!
if (!EventIsNull())
{}
}
}
回答2:
An often used pattern for this is something like the below (you'll see a lot of it in the classes in the System.Windows.Forms
namespace).
public abstract class MyClass
{
public event EventHandler MyEvent;
protected virtual void OnMyEvent(EventArgs e)
{
if (this.MyEvent != null)
{
this.MyEvent(this, e);
}
}
}
You would then use it in a derived class like this, optionally extending the behaviour:
public sealed class MyOtherClass : MyClass
{
public int MyState { get; private set; }
public void DoMyEvent(bool doSomething)
{
// Custom logic that does whatever you need to do
if (doSomething)
{
OnMyEvent(EventArgs.Empty);
}
}
protected override void OnMyEvent(EventArgs e)
{
// Do some custom logic, then call the base method
this.MyState++;
base.OnMyEvent(e);
}
}
来源:https://stackoverflow.com/questions/29831066/public-event-in-abstract-class