10

I believe I want a some methods and properties of a class to be unoverridable and use the base's implementation in all derived classes. How to achieve this? sealed keyword doesn't seem to work and says "method can not be sealed because it is not an override".

Cœur
  • 37,241
  • 25
  • 195
  • 267
Ivan
  • 63,011
  • 101
  • 250
  • 382

5 Answers5

16

Members are sealed by default in C# - unless they're marked as virtual, they can't be overridden in derived classes anyway.

They can be shadowed in derived classes, admittedly:

public new void SomeMethod()
{
}

... but that's not the same as overriding. There's no way you can prevent this, but if a caller uses a compile-time type of the base class, they won't end up calling this accidentally anyway.

If you could give us more details of exactly what you're trying to prevent (from both the caller's POV and the code being called) we may be able to help more.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
5

A method that is not already an override will not be overridable unless you mark it as virtual. So it sounds like in your case no action is needed.

class A
{
    public void B() {} // can't override
    public virtual C() {} // can override
    public virtual D() {} // can override
}

The sealed modifier only applies when a method is already an override of a member in the base class. This allows you to prevent overrides in subclasses of that class.

class A1 : A
{
    public void B() {} // shadows A.B.  Not a virtual method!
    public override C() {} // overrides A.C, subclasses can override
    public override sealed D() {} // overrides A.D, subclasses cannot override
                                  // (but can shadow)
}
harpo
  • 41,820
  • 13
  • 96
  • 131
  • Note: In general, it is a good idea to use the `new` keyword when knowingly shadowing a method. It isn't required (but *is* a warning) because requiring it would cause applications to break when they inadvertently hid a method (i.e., because a `new` version of the base class introduced a virtual method with the same name). – Brian Jul 05 '11 at 17:22
  • @Brian, thanks, good point. I've never intentionally shadowed a method, but I have often seen the compiler warning when I forget to add `override`. – harpo Jul 05 '11 at 18:16
2

This isn't possible. A derived class can always use the new keyword to hide (not override) its parents methods. The sealed keyword simply stops the derived class from overriding a virtual method, but it could still use new to hide the base method.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Coeffect
  • 8,772
  • 2
  • 27
  • 42
1

The "sealed" keyword can only be used, if you override a method that is virtual, but don't want a class deriving from your implementation to override it again. Declaring the method not virtual is all you need.

As other pointed out that there is in fact a "new" keyword, which allows hiding the method. But as long as you use a reference of your base class, your base method is always called:

class BaseClass
{
     public void Foo() { Console.WriteLine("Foo"); }
}

class Derived : BaseClass
{
     public new void Foo() { Console.WriteLine("Bar"); }
}

public static void Main()
{
     Derived derived = new Derived();
     derived.Foo(); // Prints "Bar"
     BaseClass baseClass = derived;
     baseClass.Foo(); // Prints "Foo"
}

Since providing a base-class only makes sense, as long as you use a "BaseClass"-pointer everywhere, your method cannot be hidden.

J. Tihon
  • 4,439
  • 24
  • 19
0

This is precisely what sealed keyword is for.

http://msdn.microsoft.com/en-us/library/ms173150.aspx

A class member, method, field, property, or event, on a derived class that is overriding a virtual member of the base class can declare that member as sealed. This negates the virtual aspect of the member for any further derived class. This is accomplished by putting the sealed keyword before the override keyword in the class member declaration.

If you've overridden a method from base class than use sealed. If you've declared a method in the class and don't want it to be overridden in any derived classes than don't mark it as virtual. Only virtual members can be overridden.

Jakub Konecki
  • 45,581
  • 7
  • 87
  • 126
  • Did you read the question in full? You don't need to seal a member unless it was declared as virtual in the first place. – Jon Skeet Jul 05 '11 at 16:28
  • @John - yes, I was still adding a bottom paragraph. – Jakub Konecki Jul 05 '11 at 16:30
  • This doesn't prevent overriding, it merely says "in my derived class (class A), I have overridden this member, but in a derived class from this derived class (class B : A), I no longer want this member to be virtual." To prevent overriding in the first place, just omit the `virtual` keyword. – Kyle Trauberman Jul 05 '11 at 16:30