views:

615

answers:

4

Today, I found something in legacy code. It has "static new" for one function. It looks like this.

class Foo
{
    public static void Do()
    {
        Console.WriteLine("Foo.Do");
    }
}

class Bar: Foo
{
    public static new void Do()
    {
        Console.WriteLine("Bar.Do");
    }
}

I don't understand the static new modifier for the Do method in class Bar. In C#, static method can only be invoked with class name instead of object name. So, I don't think there is any difference between having the "new" and not.

Generally, if some syntax is unnecessary, C# just treat it is error. Anybody has any idea about why C# allows such syntax?

+4  A: 

have a look at this

public class BaseC
{
    public static int x = 55;
    public static int y = 22;
}

public class DerivedC : BaseC
{
    // Hide field 'x'.
    new public static int x = 100;

    static void Main()
    {
        // Display the new value of x:
        Console.WriteLine(x);

        // Display the hidden value of x:
        Console.WriteLine(BaseC.x);

        // Display the unhidden member y:
        Console.WriteLine(y);
    }
}
/*
Output:
100
55
22
*/

Your example, to make it clear, should be

public class Foo
{
    public static void Do() {}
}
public class Bar :Foo
{
    public new static void Do() {}
}
Andreas Niedermair
+7  A: 

If you remove the new from your code you get:

warning CS0108: 'Bar.Do()' hides inherited member 'Foo.Do()'. Use the new keyword if hiding was intended.

The C# compiler just warns you that you might be doing something you did not intend and asks you to insert the new keyword to confirm that you know what you are doing. Besides suppressing the warning, it has no other effects.

Rasmus Faber
It's worth noting that it _only_ suppresses a warning. No other effects.
Henk Holterman
Good point. I added that to the anwer.
Rasmus Faber
while it only suppresses the warning, it makes the intention explicit (to avoid any confusion), check my answer
eglasius
+3  A: 

In your example, the second class Bar doesn't seem to inherit from Foo. This seems to be a typo because it doesn't makes sense otherwise.

Assuming it to be a typo, the "new" modifier explicitly hides the base class version of the function Do(). This means that the derived version of the Do() method effectively replaces the base class version.

Using "new" here documents the fact that the inherited method is intended as a replacement for the base class version of Do().

For more information, see new Modifier (C#)

Cerebrus
+2  A: 

That applies only for external callers. Remember that you can call a static method of the base class, so something like this is valid:

class Foo
{
    public static void Do() { Console.WriteLine("Foo.Do"); }
}
class Bar : Foo // :Foo added
{
    public static void Something()
    {
        Do();
    }
}

This is why the warning tells you to put the new, you want to avoid any confusion when doing this:

class Foo
{
    public static void Do() { Console.WriteLine("Foo.Do"); }
}
class Bar : Foo // :Foo added
{
    public static void Something()
    {
        Do();
    }
    public static new void Do() { Console.WriteLine("Bar.Do"); }
}
eglasius