这个问题确实是有点意义的,但我只是好奇:
这个:
public sealed class MyClass
{
protected void MyMethod(){}
}
编译,但会发出警告
而这个:
public sealed class MyClass
{
public virtual void MyMethod(){}
}
不能编译。 只是出于纯粹的好奇,是有什么原因呢?
这个问题确实是有点意义的,但我只是好奇:
这个:
public sealed class MyClass
{
protected void MyMethod(){}
}
编译,但会发出警告
而这个:
public sealed class MyClass
{
public virtual void MyMethod(){}
}
不能编译。 只是出于纯粹的好奇,是有什么原因呢?
我能想到的唯一理由是,有时你需要写保护的方法覆盖其他保护方法。 语言可以被设计为允许这样的:
protected override void Foo()
但是这不
protected void Foo()
但是,很可能已经被看作是有点难以遵循-这是没有 override
这使得它没用,而在的情况下,
public virtual void Foo()
它的存在 virtual
那是没用的。 的东西“错误”的存在是可能更容易比没有的一些有用的东西理解。
在这种情况下,是虚拟的也可能会影响性能,而使得一些受保护的,而不是私人可能不 - 所以这是一个有点更严重。
这些都只是猜测,虽然真的 - 如果我们真的很幸运,埃里克利珀会得到更明确的答案。 他是你想要的,不是我一个:)
最佳答案:警告视为错误和他们等同无论如何;)
虚拟用于声明的方法/属性“覆盖-能”。
密封被用于声明类不能从继承。
因此,在一个密封类虚方法永远无法被重写,作为类永远被继承。 它只是没有任何意义。
保护的影响访问构件,它不声明它“重写-能”作为虚拟确实(虽然它以这种方式经常使用)和相应地不矛盾的。
我看不到一个很好的理由。 受保护的MyMethod可以从MyClass的调用,但绝不会从一个派生类中调用(因为MyClass的密封)。 虚拟版本也允许直接从MyClass的调用,但它是非法的方法有一个替代,因为你不能从MyClass的派生类...
密封类可以通过继承保护了会员。 当一个方法是类的一部分,它并不重要方法是如何到达那里。
在第一种情况下,在密封类受保护的方法,其相同的,如果密封类继承的保护方法。 所以它编译。
出于好奇,到底是警告给出什么?
错误是:
CS0549:“功能”是在密封类“类”一个新的虚拟部件。
首先,尽管它并没有真正意义的包括新的protected
或virtual
的成员sealed
班,CLI¹不会允许它。 CLI还允许调用使用密封类的成员callvirt
IL指令,即使编译器可以自由地与更换call
指令。
目前,我无法找到需要编译器发出上述错误ECMA-334(C#语言规范)任何东西。 它看起来像一个微软的实现增加了错误,只是因为它没有任何意义的,在一个密封类新的虚拟成员。
¹TheCLI是虚拟机,和C#编译器发出运行在它上面的字节码。 几乎这是在CLI非法任何概念也是在C#出于这个原因非法 - 但是这是C#做了一些额外的情况下(不,这是个问题)。
编辑:这似乎越来越职位标记的是解释为什么它没有意义编写代码一样,在OP。 而对于什么规则,使它他们似乎是错误的编译器错误。
密封类不能是子类,因此虚拟不是一个选项。 这样的错误。
这首先是一个有点傻,但有效的,从而警告。
我猜编译器做了一些优化,以密封类是不可能的,如果你有一个虚拟方法声明 - “不具有虚函数表”似乎是一个可能的候选人。
这只是一个猜测,但。
作为密封When applied to a class, the sealed modifier prevents other classes from inheriting from it.
在这里,我想通过一个解释你一句:
public sealed class MyClass
{
protected void MyMethod(){}
}
它给你的警告,因为实际上它是没有意义的,因为在声明一个类后,作为封你不能继承它,并为您的法protected
,所以你可以使用它的对象不能访问它的类以外的(也记住你不能创建一个子类的本,所以你不能用那招也用这种方法)。所以实际上这是没有意义的使其成为protected
这样编译器给你一个警告,但如果你把它作为public
或internal
则因为它是在这种情况下有用不会给你错误。
现在第二个:
public sealed class MyClass
{
public virtual void MyMethod(){}
}
你封你的类,现在你正在你的方法,虚拟的,这样间接您给一个报价就有人来覆盖它,并且可以通过继承成为唯一可能和这里来你类是密封的issue.That所以你不能与此class.so这就是为什么执行与继承virtual
提示错误。
我希望它会帮助你理解。
参考http://msdn.microsoft.com/en-us/library/88c54tsw.aspx
声明一个新的保护成员暗示的意图分享子孙类会员。 密封类不能有后代,所以声明一个新的保护构件是一个位一个矛盾的,正如在密封类声明一个新的虚拟方法。
至于为什么虚拟生产,而只有保护产生一个警告错误,我只能推测,也许它与新的虚拟方法需要编译器来构建数据结构类型(一个虚函数表)的事实做,而新的保护成员只有一个访问标志集 - 没有新的数据结构。 如果编译器从一个密封类创建一个虚函数表禁止的,什么应该做它,如果它遇到一个新的虚拟方法? 失败的编译。 在一个密封类的新受保护方法是毫无意义的,但不要求编译器将冒险进入禁地。