Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing a C# subclass from overwriting a method

Say I have an abstract parent class called "Parent" that implements a method called "DisplayTitle". I want this method to be the same for each subclass that inherits "Parent" - I would like a compile error if a subclass attempts to implement their own "DisplayTitle" method. How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#. I've been messing around with "sealed" and "override", but I can't get the behavior that I'm looking for.

For example, in this code:

using System;

namespace ConsoleApplication1
{
  class Parent
  {
      public void DisplayTitle() { Console.WriteLine("Parent's Title"); }
  }

  class ChildSubclass : Parent
  {
      public void DisplayTitle() { Console.WriteLine("Child's Own Implementation of Title"); 
  }

    static void Main(string[] args)
    {
        ChildSubclass myChild = new ChildSubclass();
        myChild.DisplayTitle();
        Console.ReadLine();
    }
  }
}

I'd like to receive a compile error saying that the "ChildSubClass" can't override "DisplayTitle". I currently get a warning - but it seems like this is something that I should be able to do and I don't know the proper attributes to label the method.

like image 974
user1720817 Avatar asked Oct 04 '12 17:10

user1720817


2 Answers

How can I accomplish this in C#. I believe in Java, I'd just mark the method as "final", but I can't seem to find an alternative in C#.

The rough equivalent is sealed in C#, but you normally only need it for virtual methods - and your DisplayTitle method isn't virtual.

It's important to note that ChildSubclass isn't overriding DisplayTitle - it's hiding it. Any code which only uses references to Parent won't end up calling that implementation.

Note that with the code as-is, you should get a compile-time warning advising you to add the new modifier to the method in ChildSubclass:

public new void DisplayTitle() { ... }

You can't stop derived classes from hiding existing methods, other than by sealing the class itself to prevent the creation of a derived class entirely... but callers which don't use the derived type directly won't care.

What's your real concern here? Accidental misuse, or deliberate problems?

EDIT: Note that the warning for your sample code would be something like:

Test.cs(12,19): warning CS0108:
        'ConsoleApplication1.ChildSubclass.DisplayTitle()' hides inherited
        member 'ConsoleApplication1.Parent.DisplayTitle()'. Use the new keyword
        if hiding was intended.

I suggest you turn warnings into errors, and then it's harder to ignore them :)

like image 144
Jon Skeet Avatar answered Sep 19 '22 01:09

Jon Skeet


A derived class cannot override your method, you didn't declare it virtual. Note how that's very different in C# compared to Java, all methods are virtual in Java. In C# you must explicitly use the keyword.

A derived class can hide your method by using the same name again. This is probably the compile warning you are talking about. Using the new keyword suppresses the warning. This method does not in any way override your original method, your base class code always calls the original method, not the one in the derived class.

like image 26
Hans Passant Avatar answered Sep 18 '22 01:09

Hans Passant