c#不会在基类中使用新的重写方法
我有类似的东西c#不会在基类中使用新的重写方法,c#,events,inheritance,overriding,C#,Events,Inheritance,Overriding,我有类似的东西 class Super{ public event EventHandler MyEvent; public void Enable(){ MyEvent+=AtEvent; } public void Disable(){ MyEvent-=AtEvent; } protected void AtEvent(object sender,EventArgs e){ AllThatJazz(); } } class Child:S
class Super{
public event EventHandler MyEvent;
public void Enable(){
MyEvent+=AtEvent;
}
public void Disable(){
MyEvent-=AtEvent;
}
protected void AtEvent(object sender,EventArgs e){
AllThatJazz();
}
}
class Child:Super{
protected new void AtEvent(object sender,EventArgs e){
try{
base.AtEvent(sender,e);
}catch(ObjectDisposedException){}
}
}
class Program{
public static void Main(){
Child c = new Child();
c.Enable();
}
}
c、 Enable()将基类的事件处理程序附加到MyEvent,而不是子类的新AtEvent方法。有人能解释一下吗?
我很感谢您对备选方案的建议,但请注意Super是在一个单独的程序集中。
AtEvent
不是虚拟的,而是密封的。您从基类中的方法调用它,因此它将静态绑定到该方法的特定实现。调用该方法的最派生的实现需要是虚拟的(并且重写而不是隐藏的),或者需要从对静态键入到Child
的对象的引用调用该方法,这在调用AtEvent
的地方不是当前的情况,因为该方法不编译base.AtEvent()
没有足够的参数。请查找虚拟并覆盖c#关键字。在方法声明中远离new
修饰符,除非您喜欢程序的模糊行为…Super在一个单独的程序集中您指的是什么“从对静态键入为Child
“@nRomai我说的就是这个意思。您需要对类型为Child
的变量访问AtEvent
,才能访问子变量的实现。目前,您的代码是从父类类型的变量访问该方法的,因此使用的是父类的实现。这似乎没有帮助-这样的变量必须在超类的范围内…@nRomai是的,这当然是不可能的。这就是密封方法的本质。密封方法的全部要点是,您不希望调用更派生的实现,也不希望继承类能够将方法调用的绑定更改为它们自己的实现。如果他们想调用更派生的实现,那么方法应该是虚拟的。代码的行为是这样的,因为这正是密封方法的工作原理。