为什么私有虚拟方法在C#中是非法的?

时间:2010-06-21 05:30:23

标签: c# virtual private

来自C ++背景,这让我感到惊讶。在C ++中,将虚拟函数设为私有是一种很好的做法。来自http://www.gotw.ca/publications/mill18.htm:“准则#2:更喜欢将虚拟功能设为私有。”

我还引用了Eric Lippert的博客,来自Knights-knaves-protected-and-internal

  

私有虚拟方法在C#中是非法的,这让我感到厌烦。一世   如果有的话,我会完全使用这个功能。

我理解在C#中,您将无法覆盖派生(但不是嵌套)类中的私有虚方法。为什么会这样?在C ++中,访问说明符与是否可以覆盖函数无关。

6 个答案:

答案 0 :(得分:37)

答案 1 :(得分:15)

因为私有方法只能从定义它们的类访问,因此私有虚方法将是无用的。你想要的是一个受保护的虚拟方法。受保护的方法可以由定义它的类和任何子类访问。

编辑:

通过提供私有和受保护的关键字,C#允许您对方法进行更精细的控制。这是私有意味着完全关闭,受保护意味着完全关闭,而不是子类。这允许您拥有只有您的超类知道的方法以及子类可以知道的方法。

答案 2 :(得分:4)

我猜是因为internal virtual 几乎与private virtual 相同,对于那些不熟悉private virtual成语的人来说有点不那么容易混淆

虽然只有内部类可以覆盖private virtual方法,但只有程序集中的classess可以覆盖internal virtual方法。

答案 3 :(得分:2)

在C#中(在CLI中,就我所见),“私有”具有非常明确和明确的含义:“只能在此类中访问”。私有虚拟的概念完全搞砸了,更不用说使名称空间成为一个雷区。为什么我必须关心你所谓的方法,我甚至看不到,并得到一个编译器警告,因为它已经选择了一个你已经为它抓过的名字?

答案 4 :(得分:2)

因为C#没有任何提供公共/私有/受保护继承的机制,所以你实际上就是这样。

即使在C ++中,派生类也无法访问私有成员,但它们可以通过指定继承可见性来限制基类可见性:

class Derived : /*->>*/private/*<--*/ Base {
}

C#提供了大量其他内容,以便您控制班级成员的可见性。在protectedinternal之间,您应该能够完全按照自己的意愿获得层次结构。

恕我直言C#通过单一基类继承实施更强的IS-A关系,因此如果汽车有引擎,宝马子类不应该隐藏它,这是有道理的。

C ++支持多重继承,这是一种不那么严格的IS-A关系 - 它几乎就像一个HAS-A关系,你可以引入多个不相关的类。由于能够引入多个基类,因此您需要更严格地控​​制所有基类的可见性。

答案 5 :(得分:1)

让我说清楚:C#不是C ++。

C#是在C ++之后的几十年设计的,并且是使用多年来的先进见解构建的。在我看来,C#定义得很好,终于以正确的方式处理对象定位(imho)。它包含internal语句,原因不允许您“虚拟化”并覆盖私有方法。出于某种原因。

前面描述的所有问题(内部类重写private virtual方法,使用这种抽象工厂模式等...)可以使用接口和internal语句以不同的方式轻松编写。 话虽如此,我必须说,无论你喜欢C ++方式还是C#方式,这都是一个品味问题。

我更喜欢使用描述性代码(代码不言自明,不使用注释),而是使用接口而不是深度继承。覆盖私有虚拟方法对我来说就像是黑客或意大利面,不管它是否是常见的做法,经常使用的模式还是完成工作。

我用C ++开发已有将近1.5年的时间了,而且我从来没有遇到过覆盖私有方法的必要性......(我可以看到评论在:-))