当前位置: 首页 > 编程语言 > C#

C#-何时调用base.OnSomething?

时间:2023-04-10 15:11:50 C#

C#-何时调用base.OnSomething?我正在使用Windows.Forms并且必须继承一些控件以提供自定义行为。这种继承显然会导致方法重写。那么,问题来了——在这种情况下调用base.OnSomething(...)的顺序真的会影响程序的可见行为吗?protectedoverrideOnRetrieveVirtualItem(RetrieveVirtualItemEventArgse){//base.OnRetrieveVirtualItem(e);-这可能会破坏某些东西吗?//执行您的自定义方法。//...base.OnRetrieveVirtualItem(e);//这总是“正确的”吗?据我所知,这个顺序在重写与绘画相关的方法(OnDrawItem,...)时很重要,但我想还有其他方法可以让你大吃一惊,因为Windows.Forms会做很多事情。非托管代码调用的可能副作用。那么,什么时候可能重要?在这些情况下,选择调用基方法的正确位置有哪些经验法则?当该API的文档指定您应该调用时,您只需要调用base.SomeVirtualMethod。否则,它应该是隐式可选的。要求您调用基本方法的API没有明确说明,因此设计不佳。需要基调用的原因是糟糕的设计,因为您永远无法想象有人会覆盖您的方法将执行的操作,并且您无法确定他们会调用基方法来执行任何必需的或关键的代码。简而言之,请参阅文档,否则通常不需要。.NETFramework是根据这些准则设计的,出于这些原因,大多数虚拟方法不需要调用库。那些被记录下来的。感谢roken指出调用基本虚拟方法的一个非常重要的原因是在使用事件时。但是,我的反对意见并不总是正确的,尤其是如果您使用的是不遵循.NET惯用语和模式的第三方库或类,则不确定。例如。命名空间ConsoleApplication12{使用系统;使用系统诊断;classFoo{publicFoo(){}publiceventEventHandlerLoad;protectedvirtualvoidOnLoad(){EventHandlerhandler=Load;if(handler!=null){handler(this,newEventArgs());}Debug.WriteLine("调用Foo.OnLoad");}publicvoidRun(){OnLoad();}}classDerivedFoo:Foo{protectedoverridevoidOnLoad(){base.OnLoad();Debug.WriteLine("调用DerivedFoo.OnLoad");}}classProgram{staticvoidMain(string[]args){DerivedFoodFoo=newDerivedFoo();dFoo.Load+=(sender,e)=>{Debug.WriteLine("InvokeddFoo.Loadsubscription");};dFoo.Run();}}}如果你运行这个例子,你会得到三个调用Foo.OnLoad、DerivedFoo.OnLoad和事件订阅dFoo.Load。如果您在base.OnLoad中调用了DerivedFoo对base.OnLoad的调用,那么现在只会调用一次DerivedFoo.OnLoad,基类和订阅者都不会被调用。关于文档的问题仍然很强烈。仍然不确定基本虚方法实现是否调用其订阅者。所以这一点应该很清楚。幸运的是,感谢框架设计者,.NETFramework与.NET事件模型非常一致,但我仍然不能有足够的压力去阅读API的文档。当您根本不处理事件时,可能会发生很多事情,例如抽象基类。你怎么知道是否调用抽象类的基础事件?抽象类是否提供默认实现,或者期望您提供它?文档是为虚拟成员定义合同的最强大和最清晰的方式。这也是.NETFramework设计团队通常至少为一个抽象类提供一个具体实现的原因之一。我认为KrzysztofCwalina在框架设计指南中说得最好。我得到的一个常见问题是虚拟成员的文档是否应该说明重写必须调用基本实现。答案是覆盖应该保留基类的契约。它们可以通过调用基本实现或其他方式来实现。成员很少声称保留他们的合同(在覆盖中)的唯一方法是调用它。在许多情况下,调用base可能是保留合同的最简单方法(文档应该指出这一点),但它很少是绝对必要的。我完全同意。如果您覆盖基本实现并决定不调用它,则应提供相同的功能。我希望这能消除我在评论中的一些困惑。作为WinForms中的“经验法则”,使用On[EventName](即OnFormClosing)方法,您必须调用基方法,以便框架类触发相应的事件(否则事件将不受控制)。不管设计是否糟糕,这是一种非常常见的模式。通常,最好先调用基方法:它配置一个类。然后你运行你自己的逻辑。例如:当您覆盖OnSelectedItemChanged-您调用基本方法时,它会将您的类切换到正确的条件,然后您可以做您想做的事(执行新选择的项目)。所以了解基本方法中发生的事情会很有用。也许你不需要打电话。如何选择:只需检查DotPeek中的类,看看是否真的需要调用基方法。当重要时:基方法可以覆盖您的更改。你会得到奇怪的行为。要考虑的特殊情况:如果您使用Dispose(bool)习惯用法,则必须在清理您自己的资源后调用base.Dispose(bool)。(这和Windows.Forms有点关系,我想,因为他们使用了Dispose(bool)idiom)以上是C#学习教程:C#-Whentocallbase.OnSomething?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: