Я изучаю C #, и мне интересно, в чем смысл и преимущества переопределения ToString
, как показано в примере ниже.
Можно ли сделать это более простым способом, используя обычный метод без переопределения?
public string GetToStringItemsHeadings
{
get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}
public override string ToString()
{
string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
return strOut;
}
c#
overriding
3D-креатив
источник
источник
Console.WriteLine(obj.GetToStringItemsHeadings); Console.WriteLine(obj);
или подобного.GetToString
название свойства ... Тогда вы получите, например,Console.WriteLine(obj.ItemHeadings)
Ответы:
Вам нужно переопределить
ToString
? Нет.Можете ли вы получить строковое представление вашего объекта другим способом? Да.
Но при использовании
ToString
вы используете метод, общий для всех объектов, и поэтому другие классы знают об этом методе. Например, когда платформа .NET хочет преобразовать объект в строковое представление,ToString
это главный кандидат (есть и другие, если вы хотите предоставить более сложные параметры форматирования).Конкретно,
призовет
yourObject.ToString()
.источник
@yourObject
и<%=yourObject%>
будет "ToString-ed".ToString
не должен фактически изменять состояние объекта. Но я выступал не за это.ToString
это означает быть переопределены. Период. Оговаривать это утверждение непродуктивно. Если ты ошибаешься - твоя вина. Фактически, ваш ученик нарушил пункт 4 официального списка рекомендаций по переопределению,ToString
который был опубликован в ответе Дэвида Андерсона.Я просто дам вам ответ прямо из Руководства по проектированию инфраструктуры из серии .NET Development Series.
ИЗБЕГАЙТЕ исключения исключений из
ToString
РАССМАТРИВАЙТЕ возврат уникальной строки, связанной с экземпляром.
СЧИТАЙТЕ , что выходные данные
ToString
являются допустимыми входными данными для любых методов синтаксического анализа этого типа.ОБЯЗАТЕЛЬНО убедитесь, что у
ToString
него нет наблюдаемых побочных эффектов.НЕОБХОДИМО сообщать конфиденциальную информацию о безопасности путем переопределения
ToString
только после запроса соответствующего разрешения. Если запрос разрешения не выполняется, верните строку, исключающую конфиденциальную информацию.Object.ToString
Метод предназначен для использования для общего отображения и отладки. Реализация по умолчанию просто предоставляет имя типа объекта. Реализация по умолчанию не очень полезна, и рекомендуется переопределить метод.НЕОБХОДИМО переопределить
ToString
всякий раз, когда может быть возвращена интересная для человека строка. Реализация по умолчанию не очень полезна, а индивидуальная реализация почти всегда может обеспечить большую ценность.НЕОБХОДИМО предпочитать понятное имя уникальному, но не читаемому идентификатору.
Также стоит упомянуть, поскольку Крис Селлс также объясняет в рекомендациях, что
ToString
часто опасно для пользовательских интерфейсов. Как правило, мое практическое правило - предоставить свойство, которое будет использоваться для привязки информации к пользовательскому интерфейсу, и оставить разработчикуToString
переопределение для отображения диагностической информации. Вы также можете украсить свой шрифтDebuggerDisplayAttribute
.ДЕЙСТВИТЕЛЬНО пытайтесь сохранить строку, возвращаемую из
ToString
короткой. Отладчик используетToString
для получения текстового представления объекта, который будет показан разработчику. Если строка длиннее, чем может отобразить отладчик, процесс отладки затруднен.Форматирование строки DO на основе языка и региональных параметров текущего потока при возврате информации, зависящей от языка и региональных параметров.
НЕОБХОДИМО предоставлять перегрузку
ToString(string format)
или реализовыватьIFormattable
, если строка, возвращаемая из,ToString
зависит от языка и региональных параметров или существуют различные способы форматирования строки. Например,DateTime
предоставляет перегруз и орудияIFormattable
.НЕ возвращайте пустую строку или ноль из
ToString
Я клянусь этими правилами, и вы должны это сделать. Я не могу сказать вам, как мой код улучшился только благодаря этому руководству для
ToString
. То же самоеIEquatable(Of T)
и с такими вещами, как иIComparable(Of T)
. Эти вещи делают ваш код очень функциональным, и вы не пожалеете, что потратили дополнительное время на его реализацию.Лично я никогда не использовал
ToString
много для пользовательских интерфейсов, я всегда разоблачил свойство или метод какого-то. Большую часть времени вы должны использоватьToString
для отладки и разработки. Используйте его для отображения важной диагностической информации.источник
Переопределение
ToString()
позволяет вам дать удобное, удобочитаемое строковое представление класса.Это означает, что вывод может раскрыть полезную информацию о вашем классе. Например, если у вас есть класс Person, вы можете выбрать
ToString()
вывод идентификатора человека, его имени, фамилии и т. Д. Это чрезвычайно полезно при отладке или регистрации.Что касается вашего примера - трудно сказать, полезно ли ваше переопределение, не зная, что это за класс, но сама реализация в порядке.
источник
Это всегда уместно, но внимательно рассматривайте намерения, стоящие за тем, что вы показываете.
Лучше спросить:
ToString () - это окно в состояние объекта. Упор на состояние как требование. Языки с сильным ООП, такие как Java / C #, злоупотребляют моделью ООП, инкапсулируя все в классе. Представьте, что вы пишете код на языке, который не следует строгой модели ООП; подумайте, будете ли вы использовать класс или функцию. Если вы будете использовать его как функцию (например, глагол, действие), а внутреннее состояние поддерживается только временно между вводом / выводом, ToString () не будет добавлять значение.
Как уже упоминалось другими, важно учитывать то, что вы выводите с помощью ToString (), потому что это может использоваться отладчиком или другими системами.
Мне нравится представлять метод ToString как параметр --help объекта. Он должен быть коротким, читаемым, очевидным и легко отображаемым. Он должен отображать то, что объект не является тем, что он делает . Имея это в виду, давайте рассмотрим ...
Пример использования - разбор TCP-пакета:
Не захват сети только на уровне приложения, а что-то более содержательное, например захват pcap.
Вы хотите перегрузить ToString () только для уровня TCP, чтобы вы могли печатать данные на консоли. Что в него входит? Вы можете сойти с ума и проанализировать все детали TCP (т.е. TCP сложен) ...
Что включает в себя:
Но хотели бы вы получать весь этот мусор, если бы вызывали TCP.ToString () для 100 пакетов? Конечно, нет, это будет информационная перегрузка. Простой и очевидный выбор также самый разумный ...
Раскройте то, что люди ожидают увидеть:
Я предпочитаю разумный вывод, который легко анализировать людям, но не YMMV .
Ничего сложного, вывод не предназначен для анализа машинами (то есть, если люди не злоупотребляют вашим кодом), предполагаемая цель - удобочитаемость человека.
Но как насчет всей остальной той пикантной информации, о которой я говорил раньше, разве это тоже не полезно? Я перейду к этому, но сначала ...
ToString () один из самых ценных и малоиспользуемых методов всех времен
По двум причинам:
Причина 1. Не злоупотребляйте полезностью ToString ():
Многие люди используют ToString () для получения простого строкового представления объекта. В руководстве по C # даже говорится:
Отображение, без дальнейшей обработки. Это не значит, что возьмите мое красивое строковое представление TCP-пакета выше и извлеките исходный порт с помощью regex :: cringe ::.
Право способ сделать вещи есть, ToString вызов () непосредственно на свойстве SourcePort (которая кстати является USHORT так ToString () уже должны быть доступны).
Если вам нужно что-то более надежное, чтобы упаковать состояние сложного объекта для машинного анализа, вам будет лучше использовать стратегию структурированной сериализации.
К счастью, очень распространены такие стратегии:
Примечание: если вы не используете PHP, потому что, herp-derp, для этого есть функция :: snicker ::
Причина 2 - ToString () недостаточно:
Мне еще предстоит увидеть язык, реализующий это в основе, но я видел и использовал варианты этого подхода в дикой природе.
Некоторые из них включают:
По сути, этот беспорядок состояния TCP-пакета должен быть описан для удобства чтения человеком. Чтобы не «бить мертвую лошадь», говоря о TCP, я «укажу пальцем» на случай № 1, когда я думаю, что ToString () и ToVerboseString () используются недостаточно ...
Пример использования - массивы:
Если вы в основном используете один язык, вам, вероятно, удобен подход этого языка. Людей вроде меня, которые перепрыгивают между разными языками, количество разных подходов может раздражать.
То есть, это меня раздражало больше, чем сумма всех пальцев каждого индуистского бога вместе взятых.
Существуют различные случаи , когда языки используют общие хак и некоторые , которые получают это право . Некоторые требуют повторного изобретения колеса, некоторые делают неглубокий сброс, другие делают глубокий сброс, ни один из них не работает так, как я бы хотел ...
Я прошу очень простого подхода:
Где x - количество элементов в первом измерении, а y - количество элементов во втором измерении или какое-то значение, которое указывает на то, что 2-е измерение неровно (возможно, диапазон мин / макс?).
И:
Надеюсь, это проливает свет на тему, которая давно меня раздражает. По крайней мере, я добавил небольшую приманку для троллей, чтобы PHP-специалисты проголосовали против этого ответа.
источник
ToString()
он предназначен для отладки, то почему это единственный способ извлечь весь текст из StringBuilder - важной функции?На самом деле, речь идет о хорошей практике.
ToString()
используется во многих местах для возврата строкового представления объекта, как правило, для использования человеком. Часто ту же строку можно использовать для регидратации объекта (подумайтеint
или,DateTime
например), но это не всегда дано (например, дерево может иметь полезное строковое представление, которое просто отображает счетчик, но, очевидно, вы не можете использовать чтобы восстановить его).В частности, отладчик будет использовать это для отображения переменной в окнах просмотра, немедленных окнах и т. Д., Поэтому
ToString
на самом деле неоценим для отладки.В общем, такой тип также часто имеет явный член, который также возвращает строку. Например, пара широта / долгота может иметь, например,
ToDecimalDegrees
возврат"-10, 50"
, но он также может иметьToDegreesMinutesSeconds
, поскольку это другой формат для пары широта / долгота. Затем этот же тип может быть замененToString
одним из тех, которые предоставят значение по умолчанию для таких вещей, как отладка, или даже потенциально для таких вещей, как рендеринг веб-страниц (например,@
конструкция в Razor записываетToString()
результат нестрокового выражения в выходной поток).источник
object.ToString()
преобразует объект в его строковое представление. Если вы хотите изменить то, что возвращается, когда пользователь вызываетToString()
созданный вами класс, вам нужно будет переопределитьToString()
в этом классе.источник
Хотя я думаю, что наиболее полезная информация уже предоставлена, я добавлю свои два цента:
ToString()
предназначен для отмены. Его реализация по умолчанию возвращает имя типа, которое, хотя иногда может быть полезно (особенно при работе с большим количеством объектов), в большинстве случаев оказывается недостаточным.Помните, что в целях отладки вы можете положиться на
DebuggerDisplayAttribute
. Вы можете прочитать об этом здесь .Как правило, на POCO вы всегда можете переопределить
ToString()
. POCO - это структурированное представление данных, которое обычно может быть строкой.Создайте ToString как текстовое представление вашего объекта. Может быть, его основные поля и данные, может быть, описание количества элементов в коллекции и т. Д.
Всегда старайтесь уместить эту строку в одну строку и иметь только самую важную информацию. Если у вас есть
Person
класс со свойствами «Имя», «Адрес», «Номер» и т. Д., Возвращайте только основные данные (укажите какой-либо идентификационный номер).Будьте осторожны, чтобы не переопределить хорошую реализацию
ToString()
. Некоторые классы фреймворка уже реализованыToString()
. Отказаться от этой реализации по умолчанию - плохо: люди будут ожидать от одного результата,ToString()
а получат другой.Не бойтесь использовать
ToString()
. Единственное, о чем я буду осторожен, - это возвращать конфиденциальную информацию. В остальном риск минимален. Конечно, как отметили некоторые, другие классы будут использовать ваш ToString при обращении за информацией. Но черт возьми, когда возвращение имени типа будет считаться лучше, чем получение какой-либо фактической информации?источник
Если вы не переопределите,
ToString
вы получите реализацию базовых классов, котораяObject
является кратким именем типа класса.Если вам нужна другая, более значимая или полезная реализация,
ToString
переопределите ее.Это может быть полезно при использовании списка вашего типа в качестве источника данных для a,
ListBox
посколькуToString
он будет отображаться автоматически.Другая ситуация возникает, когда вы хотите передать свой тип,
String.Format
который вызывает,ToString
чтобы получить представление вашего типа.источник
То, что еще никто не упомянул: переопределив
ToString()
, вы также можете рассмотреть возможность реализации,IFormattable
чтобы вы могли сделать следующее:Что может быть полезно.
источник
IFormattible
интерфейс.System.Object
будет иметь переопределяемыйToString()
метод, но вы правы в том, что метод форматирования не должен бытьoverride
и действительно должен ссылаться наIFormattible
интерфейс для полного соответствия.IFormattable
принимаетIFormatProvider
параметр. Тем не менее, спасибо за редактирование вашего сообщения.Одним из преимуществ переопределения ToString () является поддержка инструментов Resharper: Alt + Ins -> «Форматирование элементов», и он записывает ToString () за вас.
источник
В некоторых случаях это упрощает чтение значений пользовательских классов в окне наблюдения отладчика. Если я точно знаю, что хочу видеть в окне просмотра, когда я заменяю ToString этой информацией, я вижу это.
источник
При определении структур (эффективно пользовательские примитивы) Я считаю , что это хорошая практика , чтобы иметь согласование
ToString
, аParse
иTryParse
методы, в частности , для XML сериализации. В этом случае вы будете преобразовывать все состояние в строку, чтобы ее можно было прочитать позже.Однако классы представляют собой более сложные структуры, которые обычно слишком сложны для использования
ToString
иParse
. ИхToString
методы, вместо сохранения всего состояния, могут представлять собой простое описание, которое поможет вам идентифицировать их состояние, например, уникальный идентификатор, такой как имя или идентификатор, или, возможно, количество для списка.Кроме того, как сказал Робби, переопределение
ToString
позволяет вам вызыватьToString
такую же базовую ссылку, как типobject
.источник
Вы можете использовать это, когда у вас есть объект, не имеющий интуитивного значения строкового представления, например person. Поэтому, если вам нужно, например, распечатать этого человека, вы можете использовать это переопределение для подготовки его формата.
источник
Этот
Object.ToString
метод следует использовать только для отладки. Реализация по умолчанию показывает имя типа объекта, что не очень полезно. Рассмотрите возможность переопределения этого метода, чтобы предоставить более точную информацию для диагностики и отладки. Учтите, что инфраструктуры ведения журналов также часто используют метод ToString, поэтому вы найдете эти текстовые фрагменты в своих файлах журналов.Не возвращайте локализованные текстовые ресурсы в
Object.ToString
методе. Причина в том, что метод ToString всегда должен возвращать то, что может понять разработчик. Разработчик может не говорить на всех языках, поддерживаемых приложением.Реализовать на
IFormattable
интерфейс , если вы хотите , чтобы вернуть удобный локализованный текст. Этот интерфейс определяет перегрузку ToString с параметрамиformat
иformatProvider
. FormatProvider помогает форматировать текст с учетом культурных особенностей.См. Также: Object.ToString и IFormattable
источник
Проще зависит от того, как ваша собственность будет использоваться. Если вам просто нужно отформатировать строку один раз, тогда нет особого смысла переопределять ее.
Однако похоже, что вы переопределяете метод ToString, чтобы он не возвращал обычные строковые данные для вашего свойства, а выполнял стандартный шаблон форматирования. Поскольку вы используете string.format с заполнением.
Поскольку вы сказали, что учитесь, это упражнение также затрагивает основные принципы объектно-ориентированного программирования, касающиеся инкапсуляции и повторного использования кода.
String.format, принимающий аргументы, которые вы установили для заполнения, гарантирует, что свойство будет форматироваться одинаково каждый раз для любого кода, который его вызывает. Кроме того, в будущем вам нужно будет изменить его только в одном месте, а не во многих.
Отличный вопрос, а также отличные ответы!
источник
Я считаю полезным переопределить метод ToString в классах сущностей, так как он помогает быстро выявлять проблемы при тестировании, особенно когда утверждение не выполняется, тестовая консоль вызывает метод ToString для объекта.
Но в соответствии с тем, что было сказано ранее, это дает удобочитаемое представление рассматриваемого объекта.
источник
Я доволен рекомендациями по структуре, упомянутыми в других ответах. Однако я хотел бы выделить цели отображения и отладки.
Будьте осторожны с тем, как вы используете
ToString
в своем коде. Ваш код не должен полагаться на строковое представление объекта. Если это так, вы обязательно должны предоставить соответствующиеParse
методы.Поскольку
ToString
его можно использовать везде, это может стать проблемой, связанной с ремонтопригодностью, если вы захотите изменить строковое представление объекта в более поздний момент времени. В этом случае вы не можете просто изучить иерархию вызовов, чтобы выяснить, не сломается ли какой-то код.источник