Why Do We Need the New Keyword and Why Is the Default Behavior to Hide and Not Override

Why do we need the new keyword and why is the default behavior to hide and not override?

Good questions. Let me re-state them.

Why is it legal to hide a method with another method at all?

Let me answer that question with an example. You have an interface from CLR v1:

interface IEnumerable
{
IEnumerator GetEnumerator();
}

Super. Now in CLR v2 you have generics and you think "man, if only we'd had generics in v1 I would have made this a generic interface. But I didn't. I should make something compatible with it now that is generic so that I get the benefits of generics without losing backwards compatibility with code that expects IEnumerable."

interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> .... uh oh

What are you going to call the GetEnumerator method of IEnumerable<T>? Remember, you want it to hide GetEnumerator on the non-generic base interface. You never want that thing to be called unless you're explicitly in a backwards-compat situation.

That alone justifies method hiding. For more thoughts on justifications of method hiding see my article on the subject.

Why does hiding without "new" cause a warning?

Because we want to bring it to your attention that you are hiding something and might be doing it accidentally. Remember, you might be hiding something accidentally because of an edit to the base class done by someone else, rather than by you editing your derived class.

Why is hiding without "new" a warning rather than an error?

Same reason. You might be hiding something accidentally because you've just picked up a new version of a base class. This happens all the time. FooCorp makes a base class B. BarCorp makes a derived class D with a method Bar, because their customers like that method. FooCorp sees that and says hey, that's a good idea, we can put that functionality on the base class. They do so and ship a new version of Foo.DLL, and when BarCorp picks up the new version, it would be nice if they were told that their method now hides the base class method.

We want that situation to be a warning and not an error because making it an error means that this is another form of the brittle base class problem. C# has been carefully designed so that when someone makes a change to a base class, the effects on code that uses a derived class are minimized.

Why is hiding and not overriding the default?

Because virtual override is dangerous. Virtual override allows derived classes to change the behaviour of code that was compiled to use base classes. Doing something dangerous like making an override should be something you do consciously and deliberately, not by accident.

What effect does the new keyword have in C# and why is it only a warning when not employed?

The only effect the new keyword has is to remove the warning. The purpose of getting the warning when not using the new keyword is to prevent you from accidentally shadowing the method when you really meant to override it.

new keyword in method signature

New keyword reference from MSDN:

MSDN Reference

Here is an example I found on the net from a Microsoft MVP that made good sense:
Link to Original

public class A
{
public virtual void One();
public void Two();
}

public class B : A
{
public override void One();
public new void Two();
}

B b = new B();
A a = b as A;

a.One(); // Calls implementation in B
a.Two(); // Calls implementation in A
b.One(); // Calls implementation in B
b.Two(); // Calls implementation in B

Override can only be used in very specific cases. From MSDN:

You cannot override a non-virtual or
static method. The overridden base
method must be virtual, abstract, or
override.

So the 'new' keyword is needed to allow you to 'override' non-virtual and static methods.

what is the reason to hide a method with the new keyword, when only returning base.method?

Let's consider the alternatives.

  1. Don't override or new anything

    Problem: There's no code on which to apply attributes.

  2. Just override it

    Problem: GetType is not virtual.

So you're left using new with a call to base.

The real question is what is so important about [EditorBrowsable(EditorBrowsableState.Never)] that they went to all this trouble? My only guess is that they felt that developers would confuse GetType with ElementType in intellisense.

Why using new when hiding methods?

No, but avoiding the warnings is incredibly important. The bugs caused by hiding can be insiduous, and after C++ (which just let you do it) both Java and C# chose two different ways to prevent them.

In Java, it is not possible to hide a base classes methods. The compiler will scream bloody murder if you try to do it.

In C#, there is the "new" keyword. It allows you to be explicit that you want to hide a method, and the compiler will warn you if you are not using it. Many developers make it a rule to have code compiler with no warnings because warnings can be a sign of bad code.

After all that, I have never had to use hiding. I would carefully consider why I was even considering using it, since its behavior is strange and almost never what I want.

C# new keyword

Why does it use base class' implementation instead of derived class' implementation

With 'new', when called on a base class variable, it will call the base class's implementation.
When called on a derived class variable, it will call the derived class's implementation.

Derived d = new Derived();
Base b = d;

d.Foo(); //<- Derived's implementation
b.Foo(); //<- Base's implementation

With 'override', the derived class's implementation is called in both cases.

Derived d = new Derived();
Base b = d;

d.Foo(); //<- Derived's implementation
b.Foo(); //<- Derived's implementation

C#: Is it OK to hide implementation by inheritance?

Is it a good practice to override/hide the behavior of the base class without actually using the override keyword?

You can't "override" the base method because it's not virtual. All you can do is hide it. It is very rarely a "good practice" but there's nothing that prevents it, so whether it's "good" or not is highly contextual.

Is it any better to use the new keyword here?

Using new doesn't change the functionality in the slightest. The keyword is there so that you can explicitly tell the compiler "I know that I'm hiding a base member". The behavior will be the same whether you use new or not.

Why do we need the new keyword and why is the default behavior to hide and not override?

Good questions. Let me re-state them.

Why is it legal to hide a method with another method at all?

Let me answer that question with an example. You have an interface from CLR v1:

interface IEnumerable
{
IEnumerator GetEnumerator();
}

Super. Now in CLR v2 you have generics and you think "man, if only we'd had generics in v1 I would have made this a generic interface. But I didn't. I should make something compatible with it now that is generic so that I get the benefits of generics without losing backwards compatibility with code that expects IEnumerable."

interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> .... uh oh

What are you going to call the GetEnumerator method of IEnumerable<T>? Remember, you want it to hide GetEnumerator on the non-generic base interface. You never want that thing to be called unless you're explicitly in a backwards-compat situation.

That alone justifies method hiding. For more thoughts on justifications of method hiding see my article on the subject.

Why does hiding without "new" cause a warning?

Because we want to bring it to your attention that you are hiding something and might be doing it accidentally. Remember, you might be hiding something accidentally because of an edit to the base class done by someone else, rather than by you editing your derived class.

Why is hiding without "new" a warning rather than an error?

Same reason. You might be hiding something accidentally because you've just picked up a new version of a base class. This happens all the time. FooCorp makes a base class B. BarCorp makes a derived class D with a method Bar, because their customers like that method. FooCorp sees that and says hey, that's a good idea, we can put that functionality on the base class. They do so and ship a new version of Foo.DLL, and when BarCorp picks up the new version, it would be nice if they were told that their method now hides the base class method.

We want that situation to be a warning and not an error because making it an error means that this is another form of the brittle base class problem. C# has been carefully designed so that when someone makes a change to a base class, the effects on code that uses a derived class are minimized.

Why is hiding and not overriding the default?

Because virtual override is dangerous. Virtual override allows derived classes to change the behaviour of code that was compiled to use base classes. Doing something dangerous like making an override should be something you do consciously and deliberately, not by accident.



Related Topics



Leave a reply



Submit