Должны ли мы всегда указывать ToString() явно?

У меня есть пользовательская структура класса следующим образом.

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

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

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

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


person Konrad Viltersten    schedule 01.07.2013    source источник
comment
Зачем вам объявлять новый ToString метод, а не переопределять существующий? Ик! (Но нет, ToString обычно не вызывается автоматически.)   -  person Jon Skeet    schedule 01.07.2013
comment
@JonSkeet Потому что согласно Интернет, override может использоваться в виртуальных методах, а ToString в Object не 'т.   -  person Konrad Viltersten    schedule 01.07.2013
comment
@KonradViltersten ToString является виртуальным.   -  person Servy    schedule 01.07.2013
comment
Ваша проблема не ясна. Все объекты ссылочного типа являются производными от объекта, поэтому все эти объекты имеют метод ToString. Когда вы создаете сложные типы, обычно метод ToString выводит имя класса вызывающего объекта (поскольку оно не было переопределено). Так где у тебя проблема? :)   -  person CarlosB    schedule 01.07.2013
comment
ToString определенно является virtual. См. документацию.   -  person Daniel Hilgarth    schedule 01.07.2013
comment
@Servy В в этом случае у меня нет дела, ха-ха. Тем не менее, кажется, что отрицательный отзыв даст мне новый значок, ха-ха. Вопрос будет удален. :D   -  person Konrad Viltersten    schedule 01.07.2013
comment
msdn.microsoft.com/en-us/library/system. объект.tostring.aspx   -  person P.Brian.Mackey    schedule 01.07.2013
comment
@JonSkeet Так же, как я не проверял документы. Просто предположил. Я собираюсь засунуть голову туда, где сейчас не светит солнце. Спасибо. :)   -  person Konrad Viltersten    schedule 01.07.2013


Ответы (2)


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

public void MustHaveString(string arg)

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

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

Затем неявно вызывается ToString, так что это необязательно.

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

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

person Tim S.    schedule 01.07.2013

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

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

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

person Jon Skeet    schedule 01.07.2013