2013-04-04 6 views
6

У меня есть два классаИспользуйте новое ключевое слово в C#

class A 
{ 
    public virtual void Metod1() 
    { 
     Console.WriteLine("A.Method1"); 
    } 
} 

class B : A 
{ 
    public new void Metod1() 
    { 
     Console.WriteLine("B.Method1"); 
    } 
} 

Тогда я пишу код, объявляющий экземпляры этих классов, и называет их методы

 static void Main(string[] args) 
    { 
     A a = new B(); 
     a.Metod1(); 
     B b = new B(); 
     b.Metod1(); 
     Console.ReadKey(); 
    } 

Я дал следующий результат:

A.Method1 
B.Method1 

Но когда я удаляю ключевое слово new из метода подписи1 класса B и запускаю главный метод, я получил тот же результат. Вопрос: Является ли новое ключевое слово в подписи методов только для лучшей читаемости?

Редактировать: Есть ли случаи, когда мы не можем обойтись без нового ключевого слова?

+0

вы должны использовать переопределение нового или в классе В bacause иначе он скрывает метод родительского элемента .. по умолчанию является новым, так что если вы не будете размещать новым он дает вам не ошибка и нормально работать. –

+0

Примечание: рассмотрите «путайте читателей и пользователей кода» как основное использование «нового» в таком контексте. Бывают случаи, когда их использование может улучшить читаемость (т. Е. Необходимо получить класс для некоторого недружественного базового класса), но в большинстве случаев это становится сложнее понять, когда будет вызван метод базового класса, и когда он будет получен. –

ответ

3

Да, вы правы, это для лучшей читаемости в этой ситуации.

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

Вы можете прочитать здесь: http://msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx

+0

Вы написали это для лучшей читаемости в этой ситуации. Но есть ситуации, когда мы не можем обойтись без нового ключевого слова – cosset

+0

@cosset Да, когда он не используется в качестве модификатора, Ie: Class1 C = new Class1() или когда вы устанавливаете для обработки предупреждений как ошибки. –

+0

Есть ситуации, когда мы не можем обойтись без нового ключевого слова в сигнатуре методов, поля – cosset

6

Knowing When to Use Override and New Keywords (C# Programming Guide)

В C# метод в производном классе может иметь такое же имя как метод в базовом классе. Вы можете указать, как взаимодействуют методы, используя новые и переопределяющие ключевые слова. Модификатор переопределения расширяет базовый метод класса , и новый модификатор скрывает его.

также

С помощью нового, вы утверждаете, что вы знаете, что член , что он изменяет скрывает элемент, который наследуется от основания класса.

+0

делает базовый класс по-прежнему нужен 'virtual' в методе для' new' в производном, чтобы иметь какое-либо влияние? В моих тестах наличие 'new' в производном классе имеет такое же поведение, что и просто отсутствие' override' - что мне не хватает? Что означает «скрывает»? – mmcrae

7

новое ключевое слово пусть читатель кода следует помнить, что этот метод будет скрывать метод с тем же именем в его базе. Даже если вы его обманули, компилятор будет рассматривать его таким же образом, но предупредит вас об этом.

Поскольку вы объявили метод как виртуального, вы получите это предупреждение при компиляции:

'B.Metod1()' скрывает унаследованный член 'A.Metod1()'. Чтобы заставить текущий элемент переопределить эту реализацию, добавьте ключевое слово переопределения. В противном случае добавьте новое ключевое слово.

Однако, если вы измените объявление путем удаления виртуального как:

  • Декларация без виртуального в A

    class A { 
        public void Metod1() { 
         Console.WriteLine("A.Method1"); 
        } 
    } 
    
    class B: A { 
        public void Metod1() { 
         Console.WriteLine("B.Method1"); 
        } 
    } 
    

будет компилироваться, но предупреждающее сообщение будет:

'B.Metod1()' скрывает унаследованный элемент 'A.Metod1()'.Используйте новое ключевое слово, если скрыто предназначено.

В любом случае, как указано выше, следующее:

  • Код испытания

    var b=new B(); 
    b.Metod1(); 
    (b as A).Metod1(); 
    

выведет:

 
B.Method1 
A.Method1 

Но, если вы объявить следование г:

  • Декларация с переопределение в B

    class A { 
        public virtual void Metod1() { 
         Console.WriteLine("A.Method1"); 
        } 
    } 
    
    class B: A { 
        public override void Metod1() { 
         Console.WriteLine("B.Method1"); 
        } 
    } 
    

Тогда результат будет:

 
B.Method1 
B.Method1 

Это потому, что Method1 базового класса не только скрыто, но переопределен производным классом.

Случай, который вы не просто использовать новый что если Method1 является абстрактный метод в абстрактном классе:

  • код, который должен использовать переопределение в производных классах

    abstract class A { 
        public abstract void Metod1(); 
    } 
    
    class B: A { 
        public override void Metod1() { // use `new` instead of `override` would not compile 
         Console.WriteLine("B.Method1"); 
        } 
    } 
    

В этом случае вы не можете просто использовать новый, потому что A требует, чтобы производные классы переопределяли Method1.

+0

Это нормально, но вопрос: Является ли новое ключевое слово в подписи методов только для лучшей удобочитаемости и есть случаи, когда мы не можем обойтись без нового ключевого слова – cosset

+0

, так что это фактически не изменяет никакого поведения - это просто для удобства чтения? – mmcrae

Смежные вопросы