2011-02-09 2 views
3

Рассмотрим следующий пример (LinqPad). ToString в классе X помечен как виртуальный. Почему вывод здесь не равен «Привет, я есть Y, Привет, я есть X», но вместо этого печатается имя типа? Конечно, маркировка ToString virtual неправильна, потому что она определена в Object как виртуальная, я просто пытаюсь понять, что здесь происходит.Маркировка ToString виртуальная в базовом классе, что происходит?

void Main() 
{ 
    Y y = new Y(); 
    Console.WriteLine(y); 
} 

// Define other methods and classes here 

class X 
{ 
    public virtual String ToString() 
    { 
    return "Hi, I'm X"; 
    } 
} 

class Y : X 
{ 
    public override String ToString() 
    { 
    return "Hi, I'm Y, " + base.ToString(); 
    } 
} 
+1

Вот большой демо на виртуальных и не виртуальных методов: http://msdn.microsoft.com/en-us/library/aa645767%28v=vs.71%29.aspx –

ответ

15

Вот создание нового виртуального метода в X под названием ToString(), скрывающую Object.ToString(). Так что если у вас есть:

Y y = new Y(); 
X x = y; 
Object o = y; 

Console.WriteLine(y.ToString()); // Shows "Hi, I'm Y, Hi, I'm X"; 
Console.WriteLine(x.ToString()); // Shows "Hi, I'm Y, Hi, I'm X"; 
Console.WriteLine(o.ToString()); // Calls object.ToString; shows just "Y" 

Вызов просто

Console.WriteLine(y); 

эквивалентна последней строке, поэтому имя типа печатается.

В принципе, ваш метод X.ToString должен переопределить в object.ToString() метод:

public override String ToString() 
{ 
    return "Hi, I'm X"; 
} 
+0

OK, делает совершенным смысл. –

8

virtual String ToString() Используя на class X, вы "скрываются" object.ToString вместо перекрывая его.

Когда вы звоните Console.WriteLine(y);, он вызывает object.ToString(). Поскольку вы не переопределили это, ваш метод никогда не вызывается.

Это, как говорится, компилятор выдаст предупреждение:

Предупреждение 1 'X.ToString() скрывает наследуется членом 'Object.ToString()'. Чтобы заставить текущий элемент переопределить эту реализацию, добавьте ключевое слово переопределения. В противном случае добавьте новое ключевое слово.

+0

В LinqPad никаких предупреждений ... хотелось бы, чтобы они были там;). –

+0

Попробуйте последнюю версию LINQPad (www.linqpad.net/beta.aspx) - теперь она должна отображать предупреждения. –

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