tags:

views:

174

answers:

4

MSDN says:

When used as a modifier, the new keyword explicitly hides a member inherited from a base class. When you hide an inherited member, the derived version of the member replaces the base-class version. Although you can hide members without the use of the new modifier, the result is a warning. If you use new to explicitly hide a member, it suppresses this warning and documents the fact that the derived version is intended as a replacement.

Example:

class Base
{
 int value;

 virtual bool Foo()
 {
   value++;
 }
}

class Derived : Base
{
 int value;

 override bool Foo()
 {
  value++;
 }

}

Do I have to add new modifier to Derived.value declaration? What changes?

+11  A: 

Since the value field is private, it's not accessible in the derived class. Thus, the declaration in the derived class does not really hide anything. You shouldn't add new to the declaration. If you do, nothing changes, except the compiler will warn you about using new incorrectly. If the value field was accessible in the derived class (e.g. it was public), then you should have used new to express your intention to hide the base member:

class A {
    public int field;
}
class B {
    public int field; // warning. `B.field` hides `A.field`. 
}

Using new will silence that warning (it will have no other effect):

class B {
    public new int field; // Dear compiler, shut up please.
}

You can't declare a method as both override and new. They are mutually exclusive.

Mehrdad Afshari
@Mehrdad It might also be helpful if you threw in an example of a good place to use the new modifier (I'd throw one up...but I don't want to create an answer just for that).
Justin Niessner
So even if I use no 'new' modifierDerived.Foo() will always access Derived.value?
Captain Comic
@Captain Comic: Yes. Unless you cast it to base explicitly like `((Base)this).value`. In general, `new` has no effect on the generated code; just on the compiler warning.
Mehrdad Afshari
+2  A: 

Given your example, Derived.value is not "hiding" Base.value. The default access modifier for C# is Private. If you make Base.value Public, then yes, using the new modifer will remove the warning.

Jim H.
Isn't the default access modifier `private`?
Broam
The default access modifier is `private` for anything except for types declared at the `namespace` level, for which `private` doesn't make sense and default is `internal`.
Mehrdad Afshari
... and by the way, you should have used `new` if it was `protected`. A `protected` field is visible in its derived classes and you'd be hiding it if declare a field with identical name.
Mehrdad Afshari
@Broam: Ah, I think you're right. vb.net's default is protected.
Jim H.
A: 

No you don't, because in this case the base method is marked as virtual, and hence it is intended that base classes override this method.

The case where you might need to use the new modifier is if the base method is not marked as virtual, for example:

class Base
{
    int value;

    public void Foo()
    {
        value++;
    }
}

class Derived : Base
{
    int value;

    new public void Foo()
    {
        value--;
    }
}

Also, in your above example we have to assume that the base Foo method is marked as public or protected, as otherwise the use of the virtual modifier is kind of pointless anyway as it won't be visible to base / other classes.

Kragen
+1  A: 

The new modifier is mainly used for hiding the non virtual methods. Unlike override modifier, it's used to hide all class members not only methods (i.e. variables and properties).

The main purpose comes when you use it to hide a method instead of using override (by the way, to hide a method, you can't use both override and new. This gives you an error not just a waning).

Using virtual and override modifiers will always be similar to using the new modifier except that when you use virtual and override you can't call the the Base class except from inside the Child class itself

Daok