В чем смысл «статического нового» модификатора для функции? - PullRequest
27 голосов
/ 19 марта 2009

Сегодня я нашел что-то в устаревшем коде. Он имеет «статическое новое» для одной функции. Похоже на это.

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

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

Я не понимаю статический новый модификатор для метода Do в классе Bar . В C # статический метод может быть вызван только с именем класса вместо имени объекта. Так что я не думаю, что есть какая-то разница между «новым» и нет.

Обычно, если какой-то синтаксис не нужен, C # просто считает, что это ошибка. Кто-нибудь имеет представление о том, почему C # позволяет такой синтаксис?

Ответы [ 4 ]

41 голосов
/ 19 марта 2009

Если вы удалите новый из своего кода, вы получите:

предупреждение CS0108: «Bar.Do ()» скрывает унаследованный элемент «Foo.Do ()». Используйте новое ключевое слово, если было скрыто.

Компилятор C # просто предупреждает вас о том, что вы, возможно, делаете то, что вы не собирались, и просит вставить ключевое слово new , чтобы подтвердить, что вы знаете, что делаете. Помимо подавления предупреждения, оно не имеет других эффектов.

13 голосов
/ 19 марта 2009

Это относится только к внешним абонентам. Помните, что вы можете вызывать статический метод базового класса, поэтому допустимо что-то вроде этого:

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

Вот почему предупреждение говорит вам поставить новое, вы хотите избежать путаницы при этом:

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"); }
}
7 голосов
/ 19 марта 2009

взгляните на это

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
*/

Ваш пример, чтобы было понятно, должен быть

public class Foo
{
    public static void Do() {}
}
public class Bar :Foo
{
    public new static void Do() {}
}
4 голосов
/ 19 марта 2009

В вашем примере Bar второго класса, похоже, не наследует от Foo. Кажется, это опечатка, потому что иначе это не имеет смысла.

Предполагая, что это опечатка, модификатор "new" явно скрывает версию функции базового класса Do(). Это означает, что производная версия метода Do() эффективно заменяет версию базового класса.

Использование здесь «new» подтверждает тот факт, что унаследованный метод предназначен для замены версии базового класса Do().

Для получения дополнительной информации см. Новый модификатор (C #)

.
...