How do I prevent a method from being overridden in a derived class?

In Java I could do this by using the final modifier on the method I wish to prevent from being overridden.

How do I achieve the same in C#?
I am aware of using sealed but apparently I can use it only with the override keyword?

class A
{
    public void methodA()
    {
        // Code.
    }

    public virtual void methodB()
    {
        // Code.
    }
}

class B : A
{
    sealed override public void methodB()
    {
        // Code.
    } 
}

So in the above example I can prevent the methodB() from being overridden by any classes deriving from class B, but how do I prevent class B from overriding the methodB() in the first place?

Update: I missed the virtual keyword in the methodB() declaration on class A when i posted this question. Corrected it.

有帮助吗?

解决方案

You don't need to do anything. The virtual modifier specifies that a method can be overridden. Omitting it means that the method is 'final'.

Specifically, a method must be virtual, abstract, or override for it to be overridden.

Using the new keyword will allow the base class method to be hidden, but it will still not override it i.e. when you call A.methodB() you will get the base class version, but if you call B.methodB() you will get the new version.

其他提示

As you mentioned, you can prevent further overriding of MethodB in class B by using sealed with override

class B : A
{
    public sealed override void methodB()
    {
        Console.WriteLine("Class C cannot override this method now");
    }
}

Use of the sealed modifier along with override prevents a derived class from further overriding the method.

If you do not want methodB in class A to be overridden by any child classes, do not mark that method virtual. Simply remove it. virtual keyword enable the method to be overridden in child classes

public void methodA()
{       
}

Use sealed keyword on your classes to prevent further overriding of the class

In C#, a function not marked virtual (which also includes overrides of virtual functions) is effectively sealed and cannot be overridden. So, your example code actually won't compile because the override keyword is not valid unless there is a method marked virtual with the same signature in a base class.

If A.methodB() were marked virtual, then you could override the method from A, but prevent it being further overridden in classes deriving more indirectly, using the sealed keyword exactly as you have shown.

One thing to keep in mind is that while method overriding can be prevented, method hiding cannot. Given your current definition of class A, the following definition of class B is legal and there's nothing you can do about it:

class B:A
 {
      public new void methodB()
            {
                    //code
            } 
  }

The new keyword basically "breaks" the inheritance/overriding hierarchy as it pertains to this one method; any reference to a class B, treated as a class B (or any further derived type) will use the implementation from class B and ignore the one from class A unless B's implementation specifically calls back to it. However, if you were to treat an instance of class B as a class A (by casting it or passing it as a parameter), then the "new" implementation is ignored.

This differs from overriding, where a class B that is being treated as a class A and truly overrides a virtual methodB would still use class B's override of the method. Also understand that method hiding is inferred (though you will get a compiler warning); if you declare a method with the same signature in a derived class and do not specify either new or override, the base class method will be hidden.

In a base class, the sealed keyword is only used to prevent a class from being derived, but in inherited classes it can be used to prevent another inherited class from overriding the method.

To prevent a base class method from being overridden, just do not specify it as virtual. In the example you provided, class B could not override methodB because methodB was not marked as virtual on the original class.

this will compile:

class A
{
    public virtual void methodA()
    {
        //code
    }
    public virtual void methodB()
    {
        //code
    }
}
class B:A
{
    public override void methodB()
    {
        //code
    } 
}

this will not:

class A
{
    public void methodA()
    {
        //code
    }
    public void methodB()
    {
        //code
    }
}
class B:A
{
    public override void methodB()
    {
        //code
    } 
}

EDITTED: clarified and corrected my original statement about the sealed keyword

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top