2

Code Snippet 1 (Compilation Error) - A.M2() cannot be sealed because it is not an override

abstract class A
{
    public abstract void M1();

    public sealed void M2()
    {
        // Do Something
    }
}

Code Snippet 2 (Works Fine)

abstract class A
{
    public abstract void M1();

    public virtual void M2()
    {

    }
}

class B : A
{
    public sealed override void M1()
    {

    }

    public sealed override void M2()
    {

    }
}

Question - If I am providing the implementation of a method in the Abstract class itself, why would C# not allow me to mark it Sealed, why would it want me to override in the sub class, there after mark it as sealed. I cannot understand this discrepancy

Mrinal Kamboj
  • 11,300
  • 5
  • 40
  • 74
  • Methods are `sealed` by default, if they're not declared as virtual and not overriding another virtual method. So, if you are providing an implementation in the base class itself, and you do not want derived classes to override that method, you do not have to mark them `virtual`, that's all. – Suresh Jun 19 '18 at 06:20
  • [This](https://stackoverflow.com/a/35476056/9676724) might make things clear – Ajay Gupta Jun 19 '18 at 06:23
  • @sthotakura methods are not sealed by default, since the new implementation can be in the sub class, which hides the older one, without any compilation error – Mrinal Kamboj Jun 19 '18 at 06:25
  • @MrinalKamboj hiding a method with a `new` implementation is different from `override`ing an implementation. You cannot override a method unless it is marked as `virtual` in the base class. – Suresh Jun 19 '18 at 06:36
  • What do you mean? Of course you can mark a method in an abstract class as sealed. Like this: `public abstract class Z { public virtual void M() { } } public abstract class A : Z { public sealed override void M() { } }` – Corak Jun 19 '18 at 07:08

2 Answers2

5

Sealed keyword can only be put on functions that are overridable. That function you specified, is not declared as a virtual function, and hence is not overridable. Also it does not make any sense for a function to be declared "virtual" and "sealed" as sealed cancels out being "virtual"

Sealed only can be used hand in hand with the "override" keyword, and stops other classes from overriding the functions themselves.

Ilan Keshet
  • 514
  • 5
  • 19
  • My question is not "How" / "What", from the code its clear what can be done, but "Why" abstract class restrict Sealed method, when it is ideally not a design issue and implementation is already available in the abstract class – Mrinal Kamboj Jun 19 '18 at 06:28
  • 2
    But it is already restricted by not specifying as a virtual function. – Ilan Keshet Jun 19 '18 at 06:29
  • 1
    You cannot mark a function as "sealed" if it wasn't already a virtual function – Ilan Keshet Jun 19 '18 at 06:30
  • What i am trying to understand is the complexity / issue if they allow non virtual method to be sealed. In any case non virtual method can be hidden in the sub class and there's only warning – Mrinal Kamboj Jun 19 '18 at 06:31
  • The answer to your "why" is just how C# was designed / built. – Ilan Keshet Jun 19 '18 at 06:33
  • @MrinalKamboj Part of C#'s design is issuing error messages for things where it isn't clear if it makes sense. Here, it flat out doesn't make sense. –  Jun 19 '18 at 06:41
  • There is a reason for method to be `virtual` and `sealed` in the same time. Interface methods can only be implemented by virtual methods, and if you does not mark it as `virtual` explicitly, then compiler [mark them as `virtual sealed` by itself](https://sharplab.io/#v2:C4LglgNgPgAgzAAjAO2AUwE4DMCGBjNBASQQG8BYAKARoRgBYEBZARgAoBKAbioF8r4CHACMAzsAz5gdAEwIAwiGJkqtOogbN2HMgn7VagzUxmdd+3kA) although you are not allowed to use that combination of modifiers yourself. – user4003407 Jun 19 '18 at 08:38
3

It has nothing to do with an abstract class. You cannot make a method as sealed in any class until it is an override method in derived class.

If you had intentions for restricting it from override in derived class then you better use private access modifier.

And the reason why you could use sealed in derived class; I've an example of it below

You have three classes A,B,C where B overrides A and C derives from B -> B:A, C:B

 abstract class A
    {
        public abstract void MyMethod();
    }

    class B : A
    {
        public sealed override void MyMethod()
        {

        }
    }

    class C : B
    {
        public override void MyMethod()
        {

        }
    }

In above example we could override method of A in B class because it is not sealed. But if you override method of B in class C then it is not allowed due to sealed keyword.

It will restrict further overrides from class B. Thats where we can use sealed

Manoz
  • 6,507
  • 13
  • 68
  • 114