С#:Как следует реализовать ToString()?[закрыто]

StackOverflow https://stackoverflow.com/questions/1404209

  •  05-07-2019
  •  | 
  •  

Вопрос

Проблемы следующие:

  • Библиотеки GUI любят использовать ToString как представление по умолчанию для классов.Там его нужно локализовать.
  • ToString используется для ведения журнала.Там он должен предоставлять информацию, связанную с программированием, не переводится и включает внутренние состояния, такие как суррогатные ключи и значения перечисления.
  • ToString используется многими строковыми операциями, которые принимают объекты в качестве аргументов, например String.Format, при записи в потоки.В зависимости от контекста вы ожидаете чего-то разного.
  • ToString слишком ограничен, если существует много разных представлений одного и того же объекта, например.длинная и краткая форма.

Из-за различий в использовании существует много разных видов реализации.Поэтому они слишком ненадежны, чтобы быть по-настоящему полезными.

Как должен ToString быть реализовано, чтобы быть полезным?Когда следует ToString можно использовать, когда его следует избегать?


А Документация по .NET Framework говорит:

Этот метод возвращает читаемую человеку строку, которая чувствительна к культуре.

Eсть аналогичный вопрос, но не то же самое.

Это было полезно?

Решение

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

Вот мои предложения:

1. Не позволяйте библиотекам GUI использовать ToString () ваших объектов. Используйте более значимые свойства (почти все элементы управления могут быть настроены для показа других свойств, чем ToString), например, используйте дисплей.2. При получении некоторой информации об объекте (для регистрации или других целей) позвольте кому-нибудь решить (другой объект или сам объект), что должно быть предоставлено и как это должно отображаться. (Может пригодиться шаблон стратегии)

Другие советы

Вот хорошая статья, которая объясняет Переопределение System.Object.ToString() и реализация IFormattable

Это зависит от предполагаемого использования вашего класса.Многие классы не имеют естественного строкового представления (т.объект формы).Затем я бы реализовал ToString как информативный метод (текст формы, размер и т. д.), полезный при отладке.Если класс предназначен для предоставления информации пользователю, я бы реализовал ToString как представление значения по умолчанию.Например, если у вас есть объект Vector, ToString может вернуть вектор как координаты X и Y.Сюда я бы еще добавил альтернативные методы, если есть другие способы описания класса.Поэтому для вектора я мог бы добавить метод, который возвращает описание в виде угла и длины.

В целях отладки вы также можете добавить в свой класс атрибут DebuggerDisplay.Это говорит о том, как отображать класс в отладчике, но не влияет на строковое представление.

Вы также можете рассмотреть возможность синтаксического анализа значения, возвращаемого ToString, чтобы можно было создать объект из строкового представления.То же самое можно сделать с методом Int32.Parse.

Еще одна проблема, которую следует учитывать, — это тесная интеграция между ToString и отладчиком Visual Studio.В окне Watch результат ToString отображается как значение выражения, поэтому, если ваш метод выполняет отложенную загрузку, имеет какие-либо побочные эффекты или занимает много времени, вы можете увидеть странное поведение или отладчик может зависнуть. .Конечно, эти качества не являются признаком хорошо спроектированного метода ToString, но они случаются (например.наивная реализация «получить перевод из базы данных»).

Следовательно, я считаю метод ToString по умолчанию (без параметров) средством отладки Visual Studio, подразумевая, что его обычно не следует перегружать для использования программой вне контекста отладки.

Хотя знающие люди используют атрибуты отладки (DebuggerTypeProxyAttribute, DebuggerDisplayAttribute, DebuggerBrowsableAttribute) для настройки отладчика, многие (включая меня) обычно считают вывод по умолчанию, сгенерированный ToString и отображаемый в окнах Watch, достаточно хорошим.

Я понимаю, что это довольно строгий взгляд — списание ToString как ловушки отладчика — но я считаю, что реализация IFormattable кажется более надежным и расширяемым путем.

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

В любом случае, вот несколько случаев, когда это имеет смысл (не исчерпывающий список):

  • Если бы результат ToString можно было проанализировать обратно в экземпляр типа без потери данных.
  • Когда тип имеет простой (т.е.не сложное) значение.
  • Когда основной целью типа является форматирование данных в текст.

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

Таким образом, конфликта нет, поскольку в соответствии с принципом единой ответственности они не должны быть одного и того же типа.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top