В чем смысл "статического нового" модификатора для функции?
Сегодня я нашел что-то в устаревшем коде. Он имеет "статическое новое" для одной функции. Это выглядит так.
class Foo
{
public static void Do()
{
Console.WriteLine("Foo.Do");
}
}
class Bar: Foo
{
public static new void Do()
{
Console.WriteLine("Bar.Do");
}
}
Я не понимаю модификатор static new для метода Do в классе Бар. В С# статический метод может быть вызван только с именем класса вместо имени объекта. Итак, я не думаю, что есть разница между "новым" и нет.
В общем случае, если какой-то синтаксис не нужен, С# просто обрабатывает ошибку.
Кто-нибудь имеет представление о том, почему С# допускает такой синтаксис?
Ответы
Ответ 1
Если вы удалите новый из своего кода, вы получите:
предупреждение CS0108: "Bar.Do()" скрывает унаследованный элемент "Foo.Do()". Используйте новое ключевое слово, если нужно было скрывать.
Компилятор С# просто предупреждает вас о том, что вы, возможно, делаете то, чего не хотели, и попросите вставить ключевое слово новое, чтобы подтвердить, что вы знаете, что вы делаете. Помимо подавления предупреждения, он не имеет других эффектов.
Ответ 2
Это относится только к внешним абонентам. Помните, что вы можете вызвать статический метод базового класса, поэтому что-то вроде этого действительно:
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"); }
}
Ответ 3
посмотрите 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
*/
В вашем примере, чтобы это было ясно, должно быть
public class Foo
{
public static void Do() {}
}
public class Bar :Foo
{
public new static void Do() {}
}
Ответ 4
В вашем примере бар второго класса, похоже, не наследуется от Foo. Кажется, это опечатка, потому что в противном случае это не имеет смысла.
Предполагая, что это опечатка, "новый" модификатор явно скрывает версию базового класса функции Do()
. Это означает, что производная версия метода Do()
эффективно заменяет версию базового класса.
Использование "нового" здесь документирует тот факт, что унаследованный метод предназначен для замены версии базового класса Do()
.
Для получения дополнительной информации см. новый модификатор (С#)