2009-06-18 4 views
17

Я хочу переопределить функцию ToString() в одном из моих классов.C#: public new string ToString() VS public override string ToString()

Я написал

public string ToString() 

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

public new string ToString() 

или

public override string ToString() 

В чем разница? Почему C# требует что-то вроде этого?

+0

+1 за написание вашего имени толкового путем ;-p (и за это время резонным вопроса ...) –

ответ

32

Если вы используете public string ToString(), не понятно, что вы сделали предназначенный для. Если вы хотите изменить поведение ToString через полиморфизм, то override. Вы могли добавить new ToString(), но это было бы глупо. Не делай этого!

Разница заключается в том, что происходит, когда вы делаете:

MyType t = new MyType(); 
object o = t; 
Console.WriteLine(t.ToString()); 
Console.WriteLine(o.ToString()); 

Если вы override, как выход будет ваша новая версия. Если вы new, только первая будет использовать вашу новую версию; второй будет использовать первоначальную реализацию.

Я не думаю, что я когда-либо видел метод использования кто-нибудь скрытие (ака new) на ToString().

+1

Приятный пример кода. Я работал над чем-то подобным. – RichardOD

+0

спасибо, очень ясно и полезно – marcgg

+0

К сожалению, я видел несколько примеров скрытия метода в C#. Ни один из них не был красивым. – JaredPar

9

Проблема в том, что ToString является виртуальным методом. Чтобы переопределить виртуальный метод в C#, вам нужно указать ключевое слово переопределения.

Вы почти наверняка не хотите «новой» версии. ,

2

Вы хотите переопределить. В вашем случае нет никакого преимущества скрываться в вашем случае (используя «новый»).

Вот статья на the differences between overriding and hiding.

1

C# не требует этого; Resharper делает. Это требует этого, потому что два ключевых слова представляют собой существенно различное поведение, и если вы не укажете, кто-то, читающий ваш код, может быть не совсем ясным, по умолчанию (это new.)

В этом случае вы явно хотите переопределить.

+1

На самом деле, даже без R # вы получите предупреждение об этом. Язык * не требует этого, но даже «экспресс» (бесплатная) IDE знает, что это плохая идея. –

+0

Другая причина, по которой мне нравится «Лечить предупреждения как ошибки» – lesscode

0

Что вы делаете, все зависит от поведения, которое вы хотите. This article объясняет, как поведение ToString работает в зависимости от того, как вы определили метод и какой уровень в иерархии классов вы вызываете ToString.

4

new modifier скроет или «тень» элемента с той же сигнатурой в базовом классе, где overriding предоставляет новую реализацию элемента, унаследованного от базового класса. Вот good article о различиях между затенением и переопределением.

0

Личная рекомендация от меня заключалась бы в том, чтобы не скрывать; он вызывает много двусмысленностей и мало решает.

1

ToString - это виртуальный метод в базовом классе. Чтобы заставить текущий элемент переопределить эту реализацию, добавьте ключевое слово переопределения. В противном случае добавьте новое ключевое слово.

0

Метод ToString() доступен для каждого типа в .NET, так как этот метод определяется как виртуальный метод в базовом классе System.Object, и все типы прямо или косвенно наследуются от System.Object. Если стандартная реализация метода ToString() не предназначена для вашей цели, вы можете переопределить (использовать ключевое слово override) или скрыть (использовать новое ключевое слово).

Я столкнулся со следующими двумя замечательными статьями, объясняющими причины переопределения метода ToString() и разницы между скрытием метода и переопределением метода. Существует также YouTube видео на один и те же понятия
Reason to override ToString()
Difference between method hiding and method overriding