为什么这个C#类声明编译?(Why does this C# class declaration c

2019-09-19 20:42发布

这个问题确实是有点意义的,但我只是好奇:

这个:

public sealed class MyClass
{
   protected void MyMethod(){}
}

编译,但会发出警告

而这个:

public sealed class MyClass
{
   public virtual void MyMethod(){}
}

不能编译。 只是出于纯粹的好奇,是有什么原因呢?

Answer 1:

我能想到的唯一理由是,有时你需要写保护的方法覆盖其他保护方法。 语言可以被设计为允许这样的:

protected override void Foo()

但是这不

protected void Foo()

但是,很可能已经被看作是有点难以遵循-这是没有 override这使得它没用,而在的情况下,

public virtual void Foo()

它的存在 virtual那是没用的。 的东西“错误”的存在是可能更容易比没有的一些有用的东西理解。

在这种情况下,是虚拟的也可能会影响性能,而使得一些受保护的,而不是私人可能不 - 所以这是一个有点更严重。

这些都只是猜测,虽然真的 - 如果我们真的很幸运,埃里克利珀会得到更明确的答案。 他是你想要的,不是我一个:)

最佳答案:警告视为错误和他们等同无论如何;)



Answer 2:

虚拟用于声明的方法/属性“覆盖-能”。

密封被用于声明类不能从继承。

因此,在一个密封类虚方法永远无法被重写,作为类永远被继承。 它只是没有任何意义。

保护的影响访问构件,它不声明它“重写-能”作为虚拟确实(虽然它以这种方式经常使用)和相应地不矛盾的。



Answer 3:

我看不到一个很好的理由。 受保护的MyMethod可以从MyClass的调用,但绝不会从一个派生类中调用(因为MyClass的密封)。 虚拟版本也允许直接从MyClass的调用,但它是非法的方法有一个替代,因为你不能从MyClass的派生类...



Answer 4:

密封类可以通过继承保护了会员。 当一个方法是类的一部分,它并不重要方法是如何到达那里。

在第一种情况下,在密封类受保护的方法,其相同的,如果密封类继承的保护方法。 所以它编译。

出于好奇,到底是警告给出什么?



Answer 5:

错误是:

CS0549:“功能”是在密封类“类”一个新的虚拟部件。

首先,尽管它并没有真正意义的包括新的protectedvirtual的成员sealed班,CLI¹不会允许它。 CLI还允许调用使用密封类的成员callvirt IL指令,即使编译器可以自由地与更换call指令。

目前,我无法找到需要编译器发出上述错误ECMA-334(C#语言规范)任何东西。 它看起来像一个微软的实现增加了错误,只是因为它没有任何意义的,在一个密封类新的虚拟成员。

¹TheCLI是虚拟机,和C#编译器发出运行在它上面的字节码。 几乎这是在CLI非法任何概念也是在C#出于这个原因非法 - 但是这是C#做了一些额外的情况下(不,这是个问题)。

编辑:这似乎越来越职位标记的是解释为什么它没有意义编写代码一样,在OP。 而对于什么规则,使它他们似乎是错误的编译器错误。



Answer 6:

密封类不能是子类,因此虚拟不是一个选项。 这样的错误。

这首先是一个有点傻,但有效的,从而警告。



Answer 7:

我猜编译器做了一些优化,以密封类是不可能的,如果你有一个虚拟方法声明 - “不具有虚函数表”似乎是一个可能的候选人。

这只是一个猜测,但。



Answer 8:

作为密封When applied to a class, the sealed modifier prevents other classes from inheriting from it.

在这里,我想通过一个解释你一句:

public sealed class MyClass
{
   protected void MyMethod(){}
}

它给你的警告,因为实际上它是没有意义的,因为在声明一个类后,作为封你不能继承它,并为您的法protected ,所以你可以使用它的对象不能访问它的类以外的(也记住你不能创建一个子类的本,所以你不能用那招也用这种方法)。所以实际上这是没有意义的使其成为protected这样编译器给你一个警告,但如果你把它作为publicinternal则因为它是在这种情况下有用不会给你错误。

现在第二个:

public sealed class MyClass
{
   public virtual void MyMethod(){}
}

你封你的类,现在你正在你的方法,虚拟的,这样间接您给一个报价就有人来覆盖它,并且可以通过继承成为唯一可能和这里来你类是密封的issue.That所以你不能与此class.so这就是为什么执行与继承virtual提示错误。

我希望它会帮助你理解。

参考http://msdn.microsoft.com/en-us/library/88c54tsw.aspx



Answer 9:

声明一个新的保护成员暗示的意图分享子孙类会员。 密封类不能有后代,所以声明一个新的保护构件是一个位一个矛盾的,正如在密封类声明一个新的虚拟方法。

至于为什么虚拟生产,而只有保护产生一个警告错误,我只能推测,也许它与新的虚拟方法需要编译器来构建数据结构类型(一个虚函数表)的事实做,而新的保护成员只有一个访问标志集 - 没有新的数据结构。 如果编译器从一个密封类创建一个虚函数表禁止的,什么应该做它,如果它遇到一个新的虚拟方法? 失败的编译。 在一个密封类的新受保护方法是毫无意义的,但不要求编译器将冒险进入禁地。



文章来源: Why does this C# class declaration compile?
标签: c# .net sealed