【发布时间】:2019-12-02 23:19:39
【问题描述】:
为什么未密封类的未密封虚拟方法调用的顺序很重要?
我正在探索 CLR via C# 一书,我遇到了以下摘录:
当一个类原本是密封的,以后可以改为非密封的 破坏兼容性。但是,一旦一个类被解封,就永远不能将其更改为sealed in 未来,因为这会破坏所有派生类。 另外,如果未密封的类定义了任何 未密封的虚拟方法,虚拟方法调用的顺序必须使用 new 维护 版本或将来有可能破坏派生类型。
有人可以以万无一失的方式解释以粗体突出显示的部分并(也许)提供一些示例吗?
我了解什么是密封/非密封类/方法,我了解什么是虚拟方法。但我不明白的是订购。摘录中提到的顺序是什么?
【问题讨论】:
-
我已经使用该框架超过 15 年(其中近十二个在微软的开发人员支持组织中 - 那时的方式)并且从未考虑过这一点;这几乎是一个边缘案例。我猜是方法调用是通过表调用来完成的。如果您在一个类型上定义了三个方法(例如 M1、M2 和 M3),那么方法表中有三个插槽,第一个包含 M1 等。如果您在基类中重新排序方法(并且不要' t 重新编译派生类),那么 slot1 最终可能会引用 M3,而对 M1 的派生类调用可能会调用 M3
-
这就是我的意思:假设您有两个虚拟方法
VM1()和VM2()。您的未密封类还有一个方法M1(),它调用这两个虚拟方法。如果M1()按VM1()后跟VM2()的顺序调用这两个虚方法,则您不能突然将M1()切换到现在在VM1()之前调用VM2()而不会破坏派生类。 -
虚拟方法的调用甚至不需要被限制在单个方法中。考虑这样一种情况:被覆盖的
VM1()做了一些被覆盖的VM2()依赖的设置。 -
如有帮助,本书可在线免费获取books.google.de/…
-
我认为@Flydog57 是正确的,到目前为止的答案并没有解决这个问题......我不认为里希特正在访问 SO,这里唯一真正的选择是如果 Eric Lippert 看到这个问题和答案...
标签: c# clr virtual sealed sealed-class