Гарні запитання. Дозвольте їх повторно заявити.
Чому взагалі законно приховувати метод за допомогою іншого методу?
Дозвольте відповісти на це запитання на прикладі. У вас є інтерфейс від CLR v1:
interface IEnumerable
{
IEnumerator GetEnumerator();
}
Супер Зараз у CLR v2 у вас є загальні засоби, і ви думаєте: "чоловіче, якби у нас були дженерики у версії 1, я б зробив це загальним інтерфейсом. Але я цього не зробив. Зараз я повинен зробити із цим щось сумісне, що є загальним, щоб Я отримую переваги дженериків, не втрачаючи зворотної сумісності з кодом, який очікує IEnumerable. "
interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> .... uh oh
Що ви збираєтеся називати методом GetEnumerator IEnumerable<T>
? Пам'ятайте, ви хочете, щоб він приховував GetEnumerator на не-загальному базовому інтерфейсі. Ви ніколи не хочете, щоб цю річ називали, якщо ви явно не знаходитесь у зворотній ситуації.
Це лише виправдовує приховування методів. Докладніше про виправдання методу приховування див. У моїй статті на цю тему .
Чому приховування без "нового" викликає попередження?
Тому що ми хочемо звернути вашу увагу, що ви щось приховуєте і, можливо, робите це випадково. Пам'ятайте, ви можете щось приховувати випадково через редагування базового класу, виконане кимось іншим, а не редагуванням похідного класу.
Чому приховування без "нового" попередження, а не помилки?
Та сама причина. Можливо, ви щось приховуєте випадково, бо щойно вибрали нову версію базового класу. Це відбувається постійно. FooCorp робить базовий клас B. BarCorp робить похідний клас D із методом Bar, оскільки їх споживачам подобається. FooCorp це бачить і каже, привіт, це гарна ідея, ми можемо покласти цю функціональність на базовий клас. Вони роблять це і постачають нову версію Foo.DLL, і коли BarCorp бере нову версію, було б непогано, якби їм сказали, що їх метод тепер приховує метод базового класу.
Ми хочемо, щоб така ситуація була попередженням, а не помилкою, оскільки її помилка означає, що це ще одна форма проблеми крихкого базового класу . C # був ретельно розроблений таким чином, що коли хтось вносить зміни до базового класу, вплив на код, який використовує похідний клас, зводиться до мінімуму.
Чому приховування, а не перевизначення за замовчуванням?
Оскільки віртуальне перевизначення небезпечно . Віртуальне заміщення дозволяє похідним класам змінювати поведінку коду, який був скомпільований для використання базових класів. Робити щось небезпечне, наприклад, робити заміну, повинно бути тим, що ви робите свідомо та навмисно , не випадково.