Why does this C# class declaration compile?

2019-06-16 17:59发布

This question really is kinda pointless, but I'm just curious:

This:

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

compiles, but gives a warning

while This:

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

doesn't compile. Just out of sheer curiosity, is there a reason for this?

标签: c# .net sealed
9条回答
仙女界的扛把子
2楼-- · 2019-06-16 18:33

virtual is used to declare a method/property "override-able".

sealed is used to declare that class cannot be inherited from.

So a virtual method in a sealed class could never be overridden, as the class could never be inherited from. It just doesn't make sense.

protected affects access to a member, it does not declare it "override-able" as virtual does (though it is often used in that manner) and is accordingly not contradictory.

查看更多
Bombasti
3楼-- · 2019-06-16 18:38

A sealed class cannot be sub-classed, therefore virtual is not an option. Thus error.

This first is a bit silly but valid, thus warning.

查看更多
我想做一个坏孩纸
4楼-- · 2019-06-16 18:44

A sealed class can have protected members via inheritance. When a method is part of a class, it doesn't matter how that method got there.

In the first case, with the protected method on the sealed class, its the same as if the sealed class inherited a protected method. So it compiles.

Out of curiosity, what exactly is the warning given?

查看更多
ゆ 、 Hurt°
5楼-- · 2019-06-16 18:47

Declaring a new protected member implies an intent to share that member with descendent classes. A sealed class cannot have descendents, so declaring a new protected member is a bit of an oxymoron, just as declaring a new virtual method in a sealed class.

As for why virtual produces an error while protected only produces a warning, I can only speculate that perhaps it has to do with the fact that new virtual methods require the compiler to build data structures for the type (a vtable), whereas new protected members only have an access flag set - no new data structure. If the compiler is prohibited from creating a vtable for a sealed class, what should it do if it encounters a new virtual method? Fail the compile. A new protected method in a sealed class is pointless but doesn't required the compiler to venture into forbidden territory.

查看更多
劳资没心,怎么记你
6楼-- · 2019-06-16 18:50

I can't see a good reason for this. The protected MyMethod can be called from MyClass, but will never be called from a derived class (because MyClass is sealed). The virtual version is also allowed to be called directly from MyClass, but it is illegal for the method to have an override because you can't derive a class from MyClass...

查看更多
劳资没心,怎么记你
7楼-- · 2019-06-16 18:51

I'd guess the compiler does some optimizations with sealed classes that are impossible if you have a virtual method declared - "not having a vtable" seems a likely candidate.

That's just a guess, though.

查看更多
登录 后发表回答