Click here to Skip to main content
15,561,817 members
Articles / Programming Languages / C#
Technical Blog
Posted 15 Dec 2009

Tagged as

Stats

25.1K views
20 bookmarked

Popular Misconception: The Override That Was Not

Rate me:
Please Sign up or sign in to vote.
5.00/5 (26 votes)
8 Sep 2017CPOL3 min read
The override that was not

I was interviewing for jobs this past week and at all of the interviews, I was presented with questions about object oriented techniques and C#. When asked about overriding a method on a class that wasn't marked as virtual, I informed the interviewers that it can't be done. I didn't realize that the interviewers were considering my answer to be wrong until yesterday when an interviewer presented to me the answer that he was looking for. He told me that I could override an otherwise unoverridable method by using the new keyword on it. That started a discussion which resulted in the interviewer wondering whether or not the method was really effectively overridden. After I had the discussion with him, I realized the earlier interviewers may have also thought that my answer was incorrect.

The misconception comes from an observation of what happens when one uses the new keyword on a method. To make this discussion a little more concrete, I'll share some example code.

C++
class MyBase
{
    public virtual string MethodA() 
    {
        return "Hello from MethodA";
    }
    public string MethodB()
    {
        return "Hello from MethodB";
    }
}

What this class does is obvious.It has two methods both of which return a unique string. The class is simple enough that I'm sure you'll trust me when I say it reliably does its job without error. One of the methods is marked as virtual, so it is overridable. The other is not. So now, I derive a class from this base class.

C++
class Derived : MyBase
{
    public override string MethodA()
    {
        return "Hello from Derived::MethodA";
    }
    public new string MethodB()
    {
        return "Hello from Derived::MethodB";
    }
}

In this derived class, I have overridden MethodA. Since MethodB is not marked as virtual, I could not override it so I used the new keyword. Let's test the program to see what type of output it produces.

C++
static void Main(string[] args)
{
    var a = new Derived();
    var b = new MyBase();

    Console.Out.WriteLine(b.MethodA());
    Console.Out.WriteLine(b.MethodB());

    Console.Out.WriteLine(a.MethodA());
    Console.Out.WriteLine(a.MethodB());
}

The output from running this is what one would expect. When I call MethodA and MethodB, the strings derived in the derived class are displayed.

Hello from MethodA
Hello from MethodB
Hello from Derived::MethodA
Hello from Derived::MethodB

Upon seeing this behaviour, it seems that the developers I spoke to last week thought this to be the functional equivalent of overriding. But the difference shows up when the instance of the class is handled through either an interface or a base class reference. Let's say I appended the following to the above code:

C++
var c = a as MyBase;

Console.Out.WriteLine(c.MethodA());
Console.Out.WriteLine(c.MethodB());

The output is not consistent with what we would expect an overridden method would produce.

Hello from Derived::MethodA
Hello from MethodB

The above output demonstrates that when a method has been overridden, then the method will be called regardless of the interface used to interact with the object instance. MethodA had been overridden so even though a variable whose type is of the base class is used, the overridden implementation is invoked. MethodB was never truly overridden so when a base class reference is used, the base class implementation is called.

So then what did the new keyword really do? It allowed someone to create a method that has the same signature and name as an existing method. While the method is called with the same notation that would have been used to call the original method, it is not actually performing an override. It is only hiding it. For confirmation, one can also look at the C# documentation for the new keyword on MSDN which refers to this as name hiding.

http://msdn.microsoft.com/en-us/library/51y09td4(VS.71).aspx#vclrfnew_newmodifier

Name hiding through inheritance takes one of the following forms:

  • A constant, field, property, or type introduced in a class or struct hides all base class members with the same name.
  • A method introduced in a class or struct hides properties, fields, and types, with the same name, in the base class. It also hides all base class methods with the same signature. For more information, see 3.6 Signatures and overloading.
  • An indexer introduced in a class or struct hides all base class indexers with the same signature.

Digging deeper into the documentation, we find the following:

The scope of an entity typically encompasses more program text than the declaration space of the entity. In particular, the scope of an entity may include declarations that introduce new declaration spaces containing entities of the same name. Such declarations cause the original entity to become hidden. Conversely, an entity is said to be visible when it is not hidden.

The conclusion: The new keyword is not performing an override, it is a scoping operator.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I attended Southern Polytechnic State University and earned a Bachelors of Science in Computer Science and later returned to earn a Masters of Science in Software Engineering. I've largely developed solutions that are based on a mix of Microsoft technologies with open source technologies mixed in. I've got an interest in astronomy and you'll see that interest overflow into some of my code project articles from time to time.



Twitter:@j2inet

Instagram: j2inet


Comments and Discussions

 
PraiseThis came up in an interview? Pin
SRTABLER20-Sep-17 4:28
SRTABLER20-Sep-17 4:28 
GeneralRe: This came up in an interview? Pin
Joel Ivory Johnson7-Nov-17 8:39
mvaJoel Ivory Johnson7-Nov-17 8:39 
GeneralMy vote of 5 Pin
Member 787034511-Sep-17 2:54
professionalMember 787034511-Sep-17 2:54 
good article
SuggestionSuggestion Pin
elmontanha11-Sep-17 0:19
elmontanha11-Sep-17 0:19 
GeneralThoughts Pin
PIEBALDconsult8-Sep-17 15:03
professionalPIEBALDconsult8-Sep-17 15:03 
SuggestionNot C++ Pin
pupstacus2-Mar-16 6:45
pupstacus2-Mar-16 6:45 
GeneralRe: Not C++ Pin
Joel Ivory Johnson28-Jul-16 9:05
mvaJoel Ivory Johnson28-Jul-16 9:05 
QuestionC# not C++ - Tagged incorrectly and in Wrong Category Pin
MstrChfBraley5-Jul-15 12:28
MstrChfBraley5-Jul-15 12:28 
GeneralMy vote of 5 Pin
Pranit Kothari10-May-12 4:21
Pranit Kothari10-May-12 4:21 
QuestionGood article... Pin
kasunt26-Oct-11 7:05
kasunt26-Oct-11 7:05 
GeneralGreat work... but... Pin
ke4vtw7-Sep-10 7:59
ke4vtw7-Sep-10 7:59 
GeneralEasier demonstration of difference Pin
supercat915-Dec-09 14:01
supercat915-Dec-09 14:01 
GeneralRe: Easier demonstration of difference Pin
Joel Ivory Johnson16-Dec-09 5:29
mvaJoel Ivory Johnson16-Dec-09 5:29 
GeneralRe: Easier demonstration of difference Pin
supercat916-Dec-09 8:09
supercat916-Dec-09 8:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.