Abstract class cannot be sealed in c#?

2019-04-07 19:54发布

问题:

I read somewhere

"Abstract and Sealed modifiers are equivalent to a class which is static"

I also found that

"When you declare a static class, internally the compiler marks the class abstract and sealed, and creates a private constructor in the IL code"

so, I decided to do this:

static class A
{
    public static void test()
    {
        Console.WriteLine("test");
    }
}

Now, the class "A" cannot be inherited nor instantiated.

So, let us write a class B using abstract to prevent instantiation and using sealed to prevent inheritance.

But, this approach fails.

which should be equivalent to

public abstract sealed class B
{
    private B()
    {

    }
    public void test()
    {
        Console.WriteLine("test");
    }
}

But I recieve an error stating "error CS0418:B': an abstract class cannot be sealed or static"` . Any ideas why this is not possible ?

Thanks in advance for your answers.

回答1:

Having checked the IL of the System.Directory class (which is static), it is declared in IL as:

.class public auto ansi abstract sealed beforefieldinit System.IO.Directory
extends System.Object
{
    ...

Further, this article (http://msdn.microsoft.com/en-us/library/ms229038.aspx) suggests that the CLR handles static classes as abstract sealed classes to support languages that do not support directly delcaring static classes (eg C++).

Thus in conclusion, static classes in C# are syntactic sugar for sealed abstract classes with private constructors. I for one am glad of that as "static" is a lot easier to write and a lot easier to get right.



回答2:

By definition a sealed class enables you to prevent the inheritance of a class or certain class members that were previously marked virtual.

Abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class. (Source: http://msdn.microsoft.com/en-us/library/ms173150.aspx)

This would imply that any class marked abstract would not be able to be sealed, since you wouldn't be able to derive it anywhere.

The code you mentioned doesn't make any sense.



回答3:

All answers somehow take the technical point of view. Such as: the class can't be "must inherit" and "can't inherit" at the same time. But I think that is not the main reason, as clearly, the "static" is just that. I think David Amo's answer has touched the real answer a bit, by stating: "it is a lot easier to get right".

I am convinced that Anders Hejlsberg's idea when designing C# was to eliminate ambiguity and thus decrease a chance for error. That's why "virtual" goes with "override" (override has to be explicit, not implicit as in Java). And in this case, "abstract"+"sealed" would be the same as "static". Two ways of defining the same principle. This is: - more error prone (imagine you have abstract somewhere and put sealed there accidently without noticing, onw compiler prevents that) - more difficult to work with (imagine you want to search for all static classes in your project)

So my point is, this entire design leads the developers the right way of doing things.