2016-12-11 6 views
3

Сегодня я узнал, что мы также можем применить модификатор наследования до new в поле const. Я использовал его для обычных полей и методов, и они имеют для меня полный смысл, поскольку они участвуют в иерархии наследования. Я попробовал свой уровень, чтобы понять применимость этого ключевого слова к полям const, но не смог. Вот несколько вещей, которые мне приходят в голову:модификатор наследования «новый» для константных полей в C#

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

Скажем, я имею два класса, как показано ниже:

class MyClass1 
{ 
    public const string PI = "3.14"; 
} 

class MyClass2 : MyClass1 
{ 
    public const string PI = "3.141"; 
} 

Для внешнего мира они всегда обращаются константы, присутствующие в этих классах, используя ClassName.FieldName синтаксис например MyClass1.PI или MyClass2.PI. Поэтому для внешнего мира не имеет значения, связаны ли MyClass1 и MyClass2 через иерархию наследования. MyClass1.PI выборки 3.14 и MyClass2.PI выборки 3.141.

Если я внутри метода экземпляра MyClass2, как показано ниже, класс полностью осознает, использует ли он статический член своего класса или статического члена своего базового класса. Он использует MyClass1.PI синтаксис, если он ссылается на статическое поле базового класса. Нет ничего, что разрешилось бы во время выполнения.

class MyClass2 : MyClass1 
{ 
    public const string PI = "3.141"; 
    string GetValueOfPi() 
    { 
     return PI; 
    } 

    string GetValueOfPiFromBaseClass() 
    { 
     return MyClass2.PI; //It clearly uses the syntax for accessing a static field of its base type 
    } 
} 

Таким образом, я не могу выяснить использования/актуальность/значимость new модификатора наследования для константных полей. В синтаксическом анализаторе кода # 1 явно предупреждает:

«MyClass2.PI» скрывает унаследованный элемент «MyClass1.PI». Используйте новое ключевое слово , если это было предназначено.

Но что кусок потребительского кода запутается или сломаться или упасть в проблему, если я не использую модификатор доступа new наследования здесь (то есть, если я не исправить предупреждение). Может ли кто-нибудь помочь мне понять концепцию, связанную с этим?

+0

Может быть, потому что переменные 'const' могут быть доступны как классу, так и имени экземпляра? –

+0

'const' - форма статического поля. поэтому те же правила применяются к полям констант. просто используйте новое ключевое слово, если хотите избавиться от предупреждения. –

+1

Возможный дубликат [Что такое пункт «статический новый» для функции?] (Http://stackoverflow.com/questions/661246/what-is-the-point-of-static-new-modifier-for -функция) –

ответ

1

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

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

class MyClass1 
{ 
    public const string PI = "3.14"; 
    public string GetValueOfPi() { return PI; } 
} 
class MyClass2 : MyClass1 
{ 
    public const string PI = "3.141"; 
} 

Теперь new MyClass2().GetValueOfPi() вернется "3.14", не "3.141". Из кода неясно, предназначил ли тот, кто его написал. Добавив ключевое слово new, вы просто говорите компилятору «да, это действительно то, что я хочу».

1

Таким образом, ваш производный класс имеет const, который вы хотите иметь различную реализацию. Для const это может произойти, только если вы используете новое ключевое слово. Для методов/свойств вы можете определить ее как виртуальную в базе и переопределить ее в производном классе или снова с помощью нового. И новое, и переопределение работает по-разному, но это не входит в ваш вопрос: Knowing When to Use Override and New Keywords, если вы хотите понять, когда его использовать.

О вашем предупреждении: Если вы не укажете новое, результирующий вывод будет таким же, как если бы вы указали новый, но вы также получите предупреждение о компиляторе (поскольку вы, возможно, не знаете, что вы скрывая метод в методе базового класса и просто забывая включить ключевое слово).