ToString () полезен только для отладки?

Кроме, конечно, их использования с примитивами. Большинство (если не все) реализаций, которые я вижу, полезны только с точки зрения программиста.


ИЗМЕНИТЬ: я понимаю, что должен переопределить поведение по умолчанию, поэтому я упомянул реализации :). И я действительно могу переопределить его в некоторых компонентах, требующих представления String внутри графического интерфейса. Однако, по крайней мере, в JDK, я вижу множество реализаций, которые используются только тогда, когда вам нужно отлаживать экземпляры объектов.

Почему он основан на классе Object, поскольку он полезен только для графического интерфейса пользователя / отладки? есть ли другие способы использования, о которых я не знаю?


person Camilo Díaz Repka    schedule 19.02.2009    source источник
comment
Ориентация вопроса на несколько языков обязательно даст разные результаты в зависимости от принятой практики этого языка.   -  person Robin    schedule 16.02.2011


Ответы (13)


toString () полезен всякий раз, когда вам нужно строковое представление объекта. Естественно, это происходит в целях отладки, но может также применяться для вывода результатов операций пользователю.

Например, предположим, что у вас есть сложный класс, который обрабатывает комплексные числа. Если вы хотите распечатать их для пользователя в формате, подобном 3 + 2i, будет удобно, если они определят toString (), поскольку вам не нужно каждый раз записывать формат, и вывод будет последовательный. Если вы когда-нибудь захотите изменить это представление, например, на 3 + 2j, вам нужно всего лишь коснуться метода toString () в классе Complex.

Таким образом, toString () также не предназначен для целей отладки, но это хороший способ получить согласованные строковые представления ваших объектов.

person raimue    schedule 19.02.2009
comment
В самом деле, но нет никакой гарантии этого consistent string representation. - person Camilo Díaz Repka; 19.02.2009
comment
У меня есть класс FooFile с FooFileSections. Чтобы записать файл, я просто переопределяю ToString для самого файла: FooFile.ToString (), а также для каждого раздела файла: FooFileSections.ToString (). затем я создаю содержимое файла, вызывая ToString в правильной последовательности для FooFileSections, а затем просто передаю текст в потоковом режиме. Наверное, в целом не лучший способ, но быстрый и легкий. - person Stein Åsmul; 09.09.2009
comment
выводить результаты операций пользователю. Поскольку toString() текст не является интернационализированным, сомнительно, насколько полезен текст в целом для пользователя. - person Raedwald; 04.02.2011

Нет, дело в том, что вы должны переопределить реализацию по умолчанию ToString(), чтобы сделать ее полезной. ToString() может быть отличным способом вывести значение чего-либо обратно в пользовательский интерфейс.

Простой пример: у вас есть класс Name с тремя строками (First, Middle, Last). У вас может быть ToString() метод, форматирующий его для пользовательского интерфейса: например, «Последний, первый средний».

Или класс, в котором хранится математическая операция (значения Left = 2, Right = 3, Result = 6 и оператор enum = Multiply). Позвоните ToString(), чтобы получить «2 * 3 = 6».

Однако, вероятно, более распространено использование множества различных To<qualifier>String() методов, таких как класс .NET DateTime. (ToShortDateString(), ToLongDateString(), ToLongTimeString(), ...)

Изменить: что касается того, почему он основан на классе Object, это просто потому, что ToString() является допустимой операцией для всего.

Кроме того, строки могут быть хорошим способом маршалинга между типами данных или потребителями данных, потому что они (практически) гарантированно поддаются синтаксическому анализу и не требуют дополнительного кодирования или ухода.

person lc.    schedule 19.02.2009
comment
Очень полное продолжение. Я просто думаю, что элементы маркировки GUI для toString () используются слишком часто. Почему не что-то вроде implements interface TextualRepresentation или что-то в этом роде? - person Camilo Díaz Repka; 19.02.2009
comment
Я согласен, что это допустимая операция для чего угодно, но только с точки зрения программиста. Я хочу сказать, что нет какого-либо контракта, в котором указывается, что метод должен предоставлять строки, удобные для графического интерфейса, или раскрывать определенные внутренние компоненты экземпляра (поля), которые полезны только для программистов, ИМХО - person Camilo Díaz Repka; 19.02.2009
comment
Часто плохо для пользовательского интерфейса, так как не требует языкового стандарта пользователя. Не имеет значения для отладки, имеет значение для конечных пользователей. - person MSalters; 19.02.2009
comment
Что касается Java, я полностью не согласен с этим ответом. Что касается C #, я понятия не имею, каковы общепринятые практики. Ориентация вопроса на несколько языков обязательно даст разные результаты в зависимости от принятой практики этого языка. - person Robin; 16.02.2011

Лично я предпочитаю, чтобы toString () никогда не использовался ни для чего, кроме отладки. Если вы хотите создать строку для объекта, предоставьте отдельный метод, который четко документирует ваше намерение (getName (), getDescription () и т. Д.). Никогда не полагайтесь на реализацию toString ().

Проблема в том, что многие разработчики видят toString () как строку уровня отладки и ничего не думают об ее изменении (например, при добавлении или удалении новых полей). Черт возьми, некоторые автоматические построители toString () используют отражение для генерации toString () из полей.

Я обнаружил, что это предпочтение хорошо мне служило на протяжении многих лет.

person Alex Miller    schedule 19.02.2009
comment
Учитывая, что String является наиболее полезной конструкцией в программировании, может быть чрезвычайно важно знать, что каждый объект в вашем программном пространстве соответствует контракту, чтобы обеспечить строковое представление самого себя. Как и в случае с чем-либо мощным, им можно злоупотреблять, но избегать этого - пустая трата времени. - person Rex M; 19.02.2009
comment
Но учитывая, что контракт а) ничего не гарантирует о формате строки и б) не предоставляет симметричного API для преобразования из String обратно в объект, я считаю, что это слабый контракт. Я отладил множество проблем, связанных с предположением о несуществующем контракте для toString. - person Alex Miller; 19.02.2009
comment
У меня точно такая же точка зрения. Я думаю, что текстовое представление меток графического интерфейса пользователя просто чрезмерно использует этот метод. - person Camilo Díaz Repka; 19.02.2009
comment
@Alex Miller - Полностью согласен. Строковое представление не означает ничего, кроме того, что оно должно быть читаемым человеком, и для любого сложного объекта не ожидайте красивого формата, просто функционального для отладки. - person Robin; 19.02.2009

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

Рассматриваемый код был библиотекой GUI, которая решила использовать значение toString как некую внутреннюю вещь (это было пару лет назад ... я забыл, что именно). Конечным результатом было то, что я больше не использовал эту библиотеку.

Я бы сказал, что, поскольку большая группа людей считает, что toString используется для отладки (независимо от вашего мнения о том, для чего, по вашему мнению, он должен использоваться), проблематично использовать возвращаемое из него значение для выполнения каких-либо программных действий. (например, проанализировать его) или показать пользователю.

Если вы на 100% контролируете методы toString, то делайте все, что хотите.

Итак, чтобы ответить на вопрос, no toString не только полезен для отладки, вы можете делать с ним все, что захотите. Однако не удивляйтесь, если toString изменится так, что вас расстроит.

person TofuBeer    schedule 19.02.2009
comment
Все, что я могу сказать, помимо отладки, это очень и очень дырявая абстракция :) - person Camilo Díaz Repka; 19.02.2009

По моему опыту, toString () не имеет большого значения вне отладки и ведения журнала. Вы не можете зависеть от его формата или содержимого с течением времени, поэтому, кроме того, что он удобочитаем, не зависите от него ни в чем другом, кроме простейших объектов (таких как примитивные типы объектов). Если есть несколько элементов данных, ожидайте, что они могут измениться по типу или количеству с течением времени, а также к выходным данным toString () вместе с ним.

Еще одно замечание, которое я хотел бы особо отметить. Не вызывайте другие методы в вашем toString (). Нет ничего хуже, чем проверка содержимого переменной в точке останова в отладчике, а затем выполнение большего количества кода из-за вызовов методов в toString ().

person Robin    schedule 19.02.2009

Я думаю, важно отметить, что люди, ответившие на упоминание «toString», заметили, что строчная буква «t» обычно говорит о Java, а люди, ответившие с упоминанием «ToString», обычно имеют в виду C #. Конечно, это относится не ко всем ответам.

По моему собственному наблюдению (я использую оба варианта ежедневно), программистам на C # рекомендуется переопределить "ToString" для отображения полезного текстового представления. В то время как в Java я этого почти не вижу. На самом деле я такое редко вижу.

-JP

person JP Richardson    schedule 19.02.2009

Во-первых, метод toString должен возвращать удобочитаемое текстовое представление объекта.

Эта проблема поднимается в Effective Java как Правило 10: Всегда переопределять toString.

Он ссылается на спецификацию Java API для _ 3_ метод:

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

Помимо отладки, переопределение метода toString класса может быть полезно при добавлении объектов в _ 5_ или JTable, который по умолчанию будет использовать метод toString для отображения объекта в виде текстовой формы в списке или таблице.

Например, в моем случае я переопределил метод toString объектов, которые добавляются в JList, чтобы пользователь мог видеть информацию об элементе в списке через графический интерфейс.

Итак, действительно есть случаи, когда метод toString полезен не только для отладки, но и для других целей. Ключ состоит в том, чтобы метод toString возвращал информацию, которая действительно полезна для человека, а не реализацию по умолчанию Object.toString, в которой место в памяти объекта используется для его текстового представления.

person coobird    schedule 19.02.2009

Полезный для

  1. Gui (сложное свойство при использовании PropertyGrid, текст заголовка формы)
  2. DataBinding (вот как это работает)

И любой другой строковый вывод.

person Avram    schedule 19.02.2009

ToString () также неявно вызывается .NET Framework при выводе любого объекта в строку.

Console.WriteLine("My Object is" + object.ToString());

эквивалентно

Console.WriteLine("My Object is" + object);

потому что неявно вызывается ToString ().

Я считаю, хотя и не уверен, что он используется отладчиком для «значения» объекта. Это может быть довольно удобно, хотя и ограничено. В большинстве случаев было бы лучше написать собственный визуализатор отладчика.

person Jeffrey Cameron    schedule 19.02.2009
comment
Отладчик может вызывать ToString () для некоторых объектов, но не для всех, как показывает List ‹something›, где вывод отладчика намного полезнее, чем вывод ToString (). - person jwg; 25.07.2013

На AS3 мне пришлось преобразовать 2D-массив в 1D-массив. Самым быстрым (скорость работы) и самым простым (время кодирования) решением было:

var new1DArray:Array = the2DArray.toString().split(",");

Удивитесь, но на самом деле он работает так, как задумано, и к тому же довольно быстро!

person LiraNuna    schedule 19.02.2009

Я часто использую ToString () для форматов даты и времени.

http://hunterconcepts.com/content/tools/formats/

person hunter    schedule 19.02.2009

Помимо того, что все уже сказали, переопределение ToString () также полезно при использовании элементов управления, которые его вызывают. Например, ComboBox:

myComboBox.Items.Add(new MyClass());
// now, whatever ToString() returns is shown in the
// ComboBox, but you can get the object back by through
// the SlectedItem property.
person Ed S.    schedule 19.02.2009

Возможно, это не "преднамеренное" использование, но я использовал его для сериализации данных.

storeToHardDrive(studentList.ToString());
person Eric    schedule 19.02.2009