Когда лучше использовать метод, а не свойство для определения класса?
Частично связанный сболее ранним моим вопросом , у меня есть система, в которой я должен хранить сложные данные в виде строки. Вместо того, чтобы анализировать эти строки как все виды отдельных объектов, я просто создал один класс, который содержит все эти объекты, и он имеет некоторую логику синтаксического анализа, которая будет кодировать все свойства в строки или декодировать строку, чтобы получить эти объекты. Это все прекрасно и хорошо. Этот вопрос не о самом синтаксическом анализаторе, а о том, где я должен разместить логику для синтаксический анализатор. Является ли это лучшим выбором, чтобы поместить его как свойство или как метод?
В случае свойства, скажем public string DataAsString
, средство доступа get
будет содержать логику для кодирования всех данных в строку, в то время как средство доступа set
будет декодировать входное значение и устанавливать все данные в экземпляре класса. Это кажется удобным, потому что вход/выход действительно является строкой.
В случае метода одним из методов будет Encode()
, который возвращает закодированную строку. Тогда либо конструктор сам бы разместил логику для декодирования строки и потребовал бы строковый аргумент, или я пишу метод Decode(string str)
, который вызывается отдельно. В любом случае он будет использовать метод вместо свойства.
Итак, существует ли функциональная разница между этими путями с точки зрения фактического выполнения кода? Или они в основном эквивалентны, и тогда все сводится к выбору личных предпочтений или какой из них выглядит лучше? И в таком вопросе... который будет выглядеть чище так или иначе?
6 ответов:
Нет никакой функциональной разницы; свойства-это просто пары методов
get
иset
с точки зрения поведения.однако , свойства, как правило, предназначены для того, чтобы быть легкими. Если геттер или сеттер вашей собственности выполняют существенные вычисления, то обычно рекомендуется переместить их в метод.
Существуют очевидные исключения из этого правила (а именно, ленивая загрузка в области ORM, где
get
может вызвать вызов базы данных).
"существительные": соглашение заключается в том, что свойства не выполняют фактическую бизнес-логику и не имеют побочных эффектов, т. е. изменяют состояние объекта (кроме установки значения).
"глаголы: методы должны работать и иметь побочные эффекты.
Такие вещи, как" преобразовать"," разобрать "или" кодировать", звучат для меня как глаголы. Я бы использовал методы.
Технически, они могут сделать то же самое. Обычно, если требуется сложная обработка, я помещаю ее в метод вместо свойства. Основная причина этого (хотя я не говорю, что люди должны предполагать это) заключается в том, что существует общее представление о том, что свойства должны обеспечивать быстрый доступ к данным, когда вызов метода предполагает, что он может занять несколько циклов. Должны ли люди предполагать это? Определенно нет, но они это делают.
Мне нравится используя методы, чтобы отметить людям, взаимодействующим с моим кодом: "Эй, это метод, идет некоторая обработка, поэтому не думайте, что вы получите немедленный результат.- У вас также не может быть асинхронного доступа к собственности. Вы можете запустить метод и получать уведомление, когда результат возвращается.
Если ваш класс будет использоваться в ситуации привязки данных,то вам понадобятся свойства. В противном случае я отсылаю вас к другим ответам.
Лично мои свойства чрезвычайно тупы, только в крайних случаях я делаю определенные проверки. т. е. проверьте, не является ли параметр null возвращаемым, и если это так, создайте его или создайте исключение
Возьмем для примера класс Person Человек.Название имеет смысл, так как собственность в данном случае. Человек.Speak () не имеет смысла как свойство.
Все зависит от того, какую функцию он выполняет.
Еще один не упомянутый момент заключается в том, что если одно или несколько свойств чтения-записи объекта записываются, а затем все они считываются без каких-либо промежуточных вызовов метода, то считанные значения должны соответствовать записанным значениям. Если запись свойства Foo приведет к изменению значения свойства read-write Bar, это, на мой взгляд, будет хорошим признаком того, что тот или иной метод должен быть парой явных методов getter-setter, а не свойством. Существует множество классов в .net, которые нарушают это принцип, но я считаю такое поведение небрежным. Возможно, самым страшным преступником является видимое свойство контроля. Запись свойства обновляет поле, состояние которого не может быть прочитано, в то время как чтение свойства возвращает результат некоторых вычислений. Лучше было бы иметь скрытое свойство для чтения и записи и видимое поле только для чтения. Кстати, на немного похожей ноте я бы сделал свойство "Length" StringBuilder доступным только для чтения, но имел методы для его усечения или заполнения; только свойство чтения-записи, которое у меня было бы, было бы значением.