【发布时间】:2011-11-21 13:42:43
【问题描述】:
我注意到,在使用 Visual Studio 覆盖 C# 中的虚拟方法时,IDE 会自动添加 base.Method() 调用。另一方面,在重写抽象方法时,IDE 会自动添加 NotImplementedException()。
为什么VS在重写虚方法时会自动添加base.Method()调用?调用基本方法是最佳做法吗?
【问题讨论】:
标签: c# visual-studio-2010 polymorphism
我注意到,在使用 Visual Studio 覆盖 C# 中的虚拟方法时,IDE 会自动添加 base.Method() 调用。另一方面,在重写抽象方法时,IDE 会自动添加 NotImplementedException()。
为什么VS在重写虚方法时会自动添加base.Method()调用?调用基本方法是最佳做法吗?
【问题讨论】:
标签: c# visual-studio-2010 polymorphism
这取决于您是否仍需要发生基本行为。该决定将根据具体情况作出。没有硬性规定,虽然有些模式会期望调用基本方法(IDisposable pattern 的正确实现是这样工作的)
【讨论】:
Visual Studio 自动生成基类调用。是否适合调用 base 取决于您选择,这取决于您覆盖的原因。
【讨论】:
如果您完全覆盖有问题的方法,人们可能会争辩说您不遵循 Liskov 替换原则的风险更高。但是没有一般规则可以遵循。
【讨论】:
抽象方法基本上是一个空方法。 IDE 添加了未实现的异常来通知该方法尚未实现并且它不能委托给基类,因为即使在那里它也没有实现。| 在虚拟方法的情况下,IDE 默认将调用该方法的基类实现,因为它至少在那里有一个实现(您可能会覆盖)
【讨论】:
这完全取决于您需要做什么。通常您需要将“基本”方法行为包含到“子”方法中,这就是为什么 VS 有助于添加语法来执行此操作。但是,并非所有情况都如此。
另一方面,实现抽象方法意味着没有可以调用的“基础”方法(毕竟,它是抽象的!),所以 VS 可以做的最好的就是将方法“标记”为未实现。
【讨论】:
考虑一下你使用 te VS 的代码生成器,但后来忘记(或决定不)填充方法体的情况。
如果您要覆盖 virtual 方法,如果您不想以任何方式改变行为,那么合理的做法是保留旧方法 - 这就是 base 调用所做的。
另一方面,当您使用override 和abstract 方法时,您没有任何base 可以引用——抽象方法根据定义没有主体。
因此,如果您未能在覆盖中提供新实现,则始终是错误。 NotImplemented 异常会引起您的注意。
有些模式需要您调用方法(例如IDisposable 或模板方法的某些情况)。在其他情况下,最好始终提供新的实现,因此这取决于场景。
【讨论】:
调用基方法取决于你想做什么:
例如,如果您覆盖控件的 OnInit 方法,如果您不调用基本方法,则默认情况下不会引发事件“Init”。如果你想完全改变方法行为,你不应该调用基本方法。比如StringBuilder类的重写方法ToString()有自己的实现,从不调用基类(对象)的ToString
我认为 Visual Studio 提出了基本调用,因为没有其他修改所有仍然有效(基本行为没有改变) 必须实现抽象方法,并将异常作为默认语句抛出应该可以帮助您提醒正确的实现
【讨论】:
添加这样的调用不会修改方法行为。
【讨论】: