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条回答
▲ chillily
2楼-- · 2019-06-16 18:53

The error is:

CS0549: 'function' is a new virtual member in sealed class 'class'.

First of all, despite the fact that it doesn't really make sense to include new protected or virtual members in a sealed class, the CLI¹ does allow it. The CLI also allows calling members of a sealed class using the callvirt IL instruction, even though a compiler could freely replace it with the call instruction.

Currently, I can't find anything in ECMA-334 (C# Language Specification) that requires the compiler emit the above error. It appears like a Microsoft's implementation added the error just because it doesn't make sense to include new virtual members in a sealed class.

¹The CLI is a virtual machine, and the C# compiler emits byte code that runs on it. Almost any concept that's illegal in the CLI is also illegal in C# for that reason - but this is a case where C# does a little extra (not that it's a problem).

Edit: It seems to posts getting marked up are explaining why it doesn't make sense to write code like that in the OP. But regarding what rule made it a compiler error they appear to be wrong.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-06-16 18:56

As sealed When applied to a class, the sealed modifier prevents other classes from inheriting from it.

here i am trying to explain you one by one:

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

it gives you warning because practically it make no sense because after declaring a class as sealed you can't inherits it and as your method is protected so you can't access it outside the class using it's object(and keep also in mind that you can't create a child class of this so you can't use this method by that trick also).So practically it makes no sense to making it protected so compiler gives you a warning but if you make it as public or internal then it will not gives you error because it's useful in that case.

now the second one:

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

as you sealed you class and now you are making your method as virtual so indirectly you are giving a offer to someone to override it and that can be only possible by inheritance and here comes the issue.That you class is sealed so you can't perform inheritance with this class.so that's why with virtual it gives error.

i hope it will help you to understand.

for reference http://msdn.microsoft.com/en-us/library/88c54tsw.aspx

查看更多
何必那么认真
4楼-- · 2019-06-16 18:57

The only reason I can think of is that sometimes you would need to write protected methods to override other protected methods. The language could have been designed to allow this:

protected override void Foo()

but not this

protected void Foo()

but that might have been seen to be a little hard to follow - it's the absence of override which makes it useless, whereas in the case of

public virtual void Foo()

it's the presence of virtual that is useless. The presence of something "wrong" is probably easier to understand than the absence of something useful.

In this case, being virtual may also have performance implications, whereas making something protected instead of private probably doesn't - so it's a bit more severe.

These are just guesses though really - if we're really lucky, Eric Lippert will give a more definitive answer. He's the one you want, not me :)

Best answer: treat warnings as errors and they're equivalent anyway ;)

查看更多
登录 后发表回答