2013-07-01 6 views
1

У меня есть структура пользовательского класса следующим образом.Должно ли мы всегда указывать ToString() явно?

public interface Stuff { } 
public Thing : Stuff 
{ 
    public new String ToString() { return "That's the thing!"; } 
} 

Затем, в других частях моего кода у меня есть метод, который принимает Струнный объект в качестве параметра. Первая строка компилируется, а вторая - нет. Я думал, что ToString был вызван по умолчанию при отправке в объект. И Материал, наследуется от Object класса должны иметь ToString уже реализованы (а также, в моем случае, омрачены моей реализации).

Thing thing = new Thing(); 
MustHaveString(thing.ToString()); 
MustHaveString(thing); 

Что мне не хватает?

+9

Почему бы вам не объявить новый метод 'ToString', а не переопределить существующий? Ик! (Но нет, ToString обычно не вызывается автоматически.) –

+0

@JonSkeet Поскольку в соответствии с [интернет] (http://social.msdn.microsoft.com/Forums/en-US/65e02299-300f-4b74-8f0a- 679f490605f5/new-vs-override-), * override * может использоваться в * виртуальных * методах и * ToString * в * Объекте * нет. –

+2

@ KonradViltersten 'ToString' * является * виртуальным. – Servy

ответ

5

Предполагая, что MustHaveString выглядит примерно так:

public void MustHaveString(string arg) 

Тогда просто говоря thing приводит к ошибке компиляции, если thing не имеет неявное преобразование в string. Без неявного преобразования вы должны сделать thing.ToString(). Однако, если ваш код, как:

string myString = "This is a thing: " + thing; 

Тогда ToString неявно вызывается, так что это необязательно.

В большинстве случаев я бы рекомендовал явно позвонить по методу ToString, чтобы пользователи поняли, что происходит.

Редактировать: поскольку этот ответ был принят, я подумал, что должен также упомянуть, что вы должны сделать свой ToString() метод override, а не new. Это приведет к обычно ожидаемому поведению, которое я описал выше.

+2

Я получил наклейку. :( –

+0

Все приветствуют короля! –

10

Возможно, вы запутались из-за звонков, таких как String.Format и Console.WriteLine, а также оператора конкатенации строк, который вызывает ToString.

Это не общее правило. В общем случае, если вам нужна строка, вам нужно либо вызвать ToString явно, либо выполнить другое преобразование. Я бы не рекомендовал создавать неявные преобразования для string - они, вероятно, вызовут больше боли, чем радости.

Я бы также рекомендовать против создания нового метода ToString. Вместо этого вы должны переопределить значение, указанное в object. Скрывать методы почти всегда плохая идея; есть несколько случаев, когда вы действительно хотите это сделать (например, для изменения типа возврата), но там, где это возможно, следует избегать.

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