8

Consider the following code:

public abstract class Test1
{
    public object Data { get; set; }
}

public abstract class Test2<T> : Test1
{
    public T Data { get; set; }
}

This will generate the following warning:

'Test2.Data' hides inherited member 'Test1.Data'. Use the new keyword if hiding was intended.

Why is this only a warning and what effect will adding the "new" keyword have?

According to my testing I cannot find any difference once the "new" keyword is added.

Don't get me wrong, I'm all for being explicit, but I was curious as to the benefit of adding "new".

My only thoughts on what it might be are:

  • Improved human readability
  • Some saving at run-time when the compiler isn't left to figure the inevitable out the long way around
joshcomley
  • 28,099
  • 24
  • 107
  • 147

4 Answers4

23

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.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
3

new is used to hide a method or property of the base class. This is not like overriding it : the member doesn't need to have the same signature as the hidden base class member, and is not involved in polymorphism.

An example :

class A
{
    public virtual void Test()
    {
        Console.WriteLine("A.Test");
    }
}

class B : A
{
    public new void Test()
    {
        Console.WriteLine("B.Test");
    }
}

class B : A
{
    public override void Test()
    {
        Console.WriteLine("C.Test");
    }
}

public static void Main(string[] args)
{
    A aa = new A();
    aa.Test(); // Prints "A.Test"

    A ab = new B();
    ab.Test(); // Prints "A.Test" because B.Test doesn't overrides A.Test, it hides it

    A ac = new C();
    ac.Test(); // Prints "C.Test" because C.Test overrides A.Test

    B b = new B();
    b.Test(); // Prints "B.Test", because the actual type of b is known at compile to be B
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • 1
    new does nothing (except suppressing a warning). The hiding happens by leaving out override. – H H Aug 10 '09 at 13:54
  • Yes, but by specifying the `new` keyword, you explicitly hide the member. Although it doesn't change anything in the end, it proves that you know what you're doing, and didn't accidentally forgot the `override` keyword – Thomas Levesque Aug 10 '09 at 14:16
  • No, hiding also happens w/o new – H H Aug 10 '09 at 14:22
  • I never said it didn't... I'm just saying that by using the `new` keyword, you *explicitly* hide the member, so there is not ambiguity on your intentions – Thomas Levesque Aug 10 '09 at 14:31
2

Turn on report warnings as errors. This will force you to be more explicit with your usage of new and override.

DanDan
  • 10,462
  • 8
  • 53
  • 69
1

Whether a derived-class method should be regarded as an override for a base-class method of the same name often depends upon whether the author of the derived-class method was aware of the base-class method and its associated contract and wrote the derived-class method to fulfill that contract. In most cases where a derived-class method has the same name and signature as a base-class method, the derived-class method would be intended to fulfill the base-class contract, but if the author of a deployed base class adds a name without realizing that the same name is used for some other purpose in a derived class, the derived-class method author cannot be presumed to have written his method to conform to the contract for a base-class method that didn't exist at the time.

There is no general means by which the C# can tell when different methods were added to classes, and thus no way for the compiler to know whether the author of a derived-class method knew anything about the existence of a like-named base class method unless the author of the derived-class method expressly indicates to the compiler whether or not he aware of the base-class method's existence by using the new or override modifiers.

I would suggest interpreting the modifiers (or lack thereof) as:

  • None -- The author is unaware of the existence of a base class method, and thus cannot be expecting to fulfill its contract.

  • new -- The author is aware of the base-class method, and for whatever reason has written this method so as not to fulfill it.

  • override -- The author is aware of the base-class method and its contract, and wrote this method to fulfill it.

The reason the compiler defaults to assuming new but with a warning is that in cases where the method is added to the derived class before the base-class method ever existed, the author cannot possibly be expected to have been aware of the base-class contract and cannot plausibly have been intending to fulfill a contract that didn't yet exist, but in cases where the derived-class method is written after the base-class method, the author should generally pick another name unless the author either intends to fulfill the base-class contract or has a specific reason for using the same name without fulfilling the contract. The compiler can't tell which method was written first, and thus has no way of knowing which behavior is appropriate.

supercat
  • 77,689
  • 9
  • 166
  • 211