我知道可以在类中引发一个实现声明发生的事件,但我希望在基类级别引发事件并引发派生类的事件:
public interface IFoo { event EventHandlerFooValueChanged; void RaiseFooValueChanged(IFooView sender, FooEventArgs e); } [TypeDescriptionProvider(typeof(FooBaseImplementor))] public abstract class FooBase : Control, IFoo { public virtual event EventHandler FooValueChanged; public void RaiseFooValueChanged(IFooView sender, FooEventArgs e) { FooValueChanged(sender, e); } }
我不能拥有FooValueChanged事件摘要,因为基类不能引发事件.当前代码运行,但调用FooValueChanged(sender,e)抛出NullReferenceException,因为它不调用派生类的事件,只调用基类的事件.
我哪里错了?
我可以将事件和提升者都抽象化,但是我需要记住在每个派生类中调用FooValueChanged(sender,e).我试图避免这种情况,同时能够使用Visual Studio设计器进行派生控件.
首先请注意,您使用的事件声明是C#中的简写符号:
public event EventHandler Event; public void RaiseEvent() { this.Event(this, new EventArgs()); }
相当于:
private EventHandler backEndStorage; public event EventHandler Event { add { this.backEndStorage += value; } remove { this.backEndStorage -= value; } } public void RaiseEvent() { this.backEndStorage(this, new EventArgs()); }
backEndStorage是一个多播委托.
现在您可以重写代码:
public interface IFoo { event EventHandlerFooValueChanged; void RaiseFooValueChanged(IFooView sender, FooEventArgs e); } [TypeDescriptionProvider(typeof(FooBaseImplementor))] public abstract class FooBase : Control, IFoo { protected event EventHandler backEndStorage; public event EventHandler FooValueChanged { add { this.backEndStorage += value; } remove { this.backEndStorage -= value; } } public void RaiseFooValueChanged(IFooView sender, FooEventArgs e) { this.backEndStorage(sender, e); } } public class FooDerived : FooBase { public event EventHandler AnotherFooValueChanged { add { this.backEndStorage += value; } remove { this.backEndStorage -= value; } } }
所以现在当在派生类上添加事件时,它们实际上将被添加到基类的backEndStorage中,因此允许基类调用在派生类中注册的委托.