Когда следует помещать данные типа Key / Value в их собственный класс вместо использования предварительно созданной общей структуры, такой как a KeyValuePair
или a Tuple
?
Например, большинство ComboBox, которые я создаю, содержат DisplayName и Value. Это тот тип данных, который я пытаюсь решить, когда добавить новый класс, а когда просто использовать KeyValuePair.
В настоящее время я работаю над тем, что использует iCalendar
, и данные выбранного пользователя в конечном итоге объединяются в key1=value1;key2=value2;
тип строки. Я начал с помещения данных в a KeyValuePair<string,string>
, но теперь мне интересно, должен ли это быть его собственный класс.
В целом, мне интересно узнать, какие руководящие указания используются при принятии решения об использовании существующей структуры / класса, например, KeyValuePair
объекта с двумя свойствами, и в каких ситуациях вы будете использовать один над другим.
источник
tuple
тип.iCalendar
и хочу объекты дляBYDAY
иBYSETPOS
. Они появляются в комбинированных списках, но фактические данные объединяются в повторяющуюся строку правила, которая являетсяkey=value;
типом строкиОтветы:
Я бы обычно использовал объект, а не KeyValuePair или Tuple в большинстве случаев. Во-первых, когда вы приходите через 6 месяцев, чтобы внести изменения, гораздо проще выяснить, каким было ваше намерение раньше, чем задаваться вопросом, что
Tuple t
и почему оно имеет эти забавные ценности. Во-вторых, по мере роста и изменения вы можете легко настроить поведение ваших простых объектов передачи данных в соответствии с требованиями. Нужно иметь два формата имени? Легко, просто добавьте соответствующие перегрузки ToString (). Нужно ли реализовать какой-то интерфейс? Нет проблем. Наконец, создание простого объекта практически не требует дополнительных затрат, особенно с автоматическими свойствами и завершением кода.Дополнительный совет: если вы хотите предотвратить загрязнение пространства имен этими объектами, создание закрытых классов внутри классов - отличный способ сохранить все в тайне и предотвратить странные зависимости.
источник
Правило определения нового класса простое: оно обобщено «Бритвой Оккама».
http://c2.com/cgi/wiki?OccamsRazor
Не вводите новые классы без уважительной причины. Или используйте готовые классы как можно больше. Или изобретать как можно меньше. Однако вы можете писать меньше кода.
Вы не можете использовать предварительно созданный класс, если вам необходимо назначить объекту уникальную ответственность, и эта ответственность не определена в предварительно созданном классе. Часто это уникальный метод.
А
tuple
илиKeyValuePair
является предпочтительным.До того как.
Вам нужны некоторые функции, которые не являются частью A
tuple
илиKeyValuePair
. Затем вы должны определить свой собственный класс.источник
tuple
илиKeyValuePair
»? KeyValuePair, по крайней мере, имеет ограниченную форму семантики, но кортежи редко (возможно, в зависимости от контекста) imho. Введение нового класса должно дать вам четкую семантику как само собой разумеющееся.Если вы пишете свой собственный класс, у вас есть четкое место для размещения документации о двух значениях. Тем более, что две строки не очень четкое определение. Однако вы могли бы написать что-то вроде
источник
MyPair
определяет значения Tuple и для чего они используются.Item1
иItem2
! Разве не так просто определить весь класс?public class SideStrings { public string Left { get; set; } public string Right { get; set; } }
С. Лотт написал
Позвольте мне сказать, почему у меня есть серьезная проблема с этим. поскольку
кажется, все в порядке .... Является ли KeyValue [строка, KeyValue [строка, KeyValuePair [строка, строка]]] также хорошо? Я не знаю, что С.Лотт скажет на это, но мой босс считает, что все в порядке.
Смею не согласиться. И вот почему: это снижает читабельность кода, который будет следовать. Функция, которая заполнит такую структуру данных, будет намного более сложной и подверженной ошибкам (ошибкам… исключение) (представьте себе хотя бы некоторую бизнес-логику). Я не слишком спорил с моим боссом, но я скажу это здесь: удобочитаемость превосходит минимальную экономию места (что было его аргументом). Так не будет объект класса, в котором есть несколько полей; но некоторые остаются пустыми, иногда лучше?
PS Я Ultra_Noob, поэтому, пожалуйста, скажите мне, если я не прав.
источник
KeyValuePair<string,string>
это нормально, если предположить, что вложенные вещи действительно являются ключами и ценностями. Здесь повторное использование существующего класса является выигрышем, поскольку вы сохраняете написание кода и получаете совместимость. OTOH, используя что-то настолько сложное, насколькоKeyValuePair<string,KeyValuePair<string,string>>
это часто бывает просто слишком сложно, чтобы быть практичным. Иногда это может быть правильным - когда вам не нужны дополнительные функции, когда смысл очевиден и когда он прекрасно работает с другими классами. YMMV, это просто взвешивание плюсов и минусов.Когда мы говорим пара ключ / значение , я обычно имею в виду хеш-таблицы , или ассоциативные массивы , или просто объект KeyValuePair . Я использую все из них, и нет разницы в том, когда я использую какой.
Я думаю, что самая важная вещь в списке пар ключ / значение состоит в том, что ключи должны быть уникальными (поскольку это ключ в конце концов), и все вышеупомянутые структуры действительно предоставляют мне эту функциональность.
Кроме этого, я хочу осуществлять поиск по ключам или выполнять действия в стиле списка (массива), такие как push и pop.
Итак, мой ответ - НЕТ , и я не создаю объекты явно для пар ключ / значение, так как многие встроенные структуры уже делают это для меня.
источник
В шестой главе Чистого кода есть хорошее описание того, когда использовать структуру данных по сравнению с классом. Короче говоря, вы используете структуру данных, когда в основном ожидаете добавления новых функций для работы с этими данными. Вы используете класс, когда вы в основном ожидаете добавления новых типов данных для работы с существующими функциями. Ваш ComboBox является примером последнего. У вас есть один набор функций (реализация ComboBox), работающих с множеством разных типов данных (разные виды данных для разных виджетов).
источник
Я бы, возможно, согласился бы с Уилдингом здесь , но тогда я тоже немного новичок в подобных вещах.
Я бы предположил, что встроенные типы часто являются объектами механизма . KeyValuePair, например, является частью механизма словаря и хеш-таблиц, помогая обеспечить уникальные ключи, и они имеют свойства, которые имеют значимые имена в контексте самого механизма.
С другой стороны, использование пользовательских объектов данных обеспечивает лучшее представление ваших данных и предоставляет множество преимуществ, включая удобочитаемость и расширяемость. Нет ничего, что могло бы остановить повторное использование существующего кода в пользовательских объектах, как предложил Sign , но я бы попытался скрыть упакованный класс и избежать утечки абстракции , чтобы вы могли изменить базовую реализацию на более позднем этапе, не затрагивая остальную часть вашего кода. ,
Итак, настоящий вопрос: представляете ли вы данные или используете данные в механизме? (и я бы не советовал смешивать эти понятия вместе).
По моему опыту, нет ничего хуже, чем видеть, как Tuple [string, string] передается в метод и не имеет непосредственного способа узнать, какими должны быть Item1 и Item2. Лучше всего использовать кортежи в методах или как частные члены класса.
источник