Свойства против методов

Быстрый вопрос: когда вы решите использовать свойства (в C #), а когда - методы?

Мы заняты этой дискуссией и нашли некоторые области, где спорно, следует ли нам использовать свойство или метод. Вот один пример:

public void SetLabel(string text)
{
    Label.Text = text;
}

В этом примере Label - это элемент управления на странице ASPX. Есть ли принцип, которым можно руководствоваться при принятии решения (в данном случае) о том, делать ли это методом или свойством?

Я приму наиболее общий и исчерпывающий ответ, но он также касается приведенного мною примера.


person Sir Rippov the Maple    schedule 02.03.2009    source источник
comment
-1 на этот вопрос уже был задан и дан ответ: stackoverflow.com/questions/164527/   -  person Element    schedule 02.03.2009
comment
Плюсы и минусы метода / поля / свойства могут вызвать долгие споры; какое-то общее использование свойств: когда вам нужны частные / защищенные поля, но в то же время вы хотите их раскрыть. Другое использование - иметь не только операторы, но и выражения (действия, если хотите), даже if() проверки (согласно MSDN). Но это сложно, поскольку пользователь не всегда осведомлен о стоимости обработки, связанной с доступом к переменной (свойству) (то есть код недоступен), и из соображений строгости необходимо провести сравнительный анализ свойства. Да, и бонус: нельзя использовать указатели со свойствами.   -  person mireazma    schedule 28.11.2016
comment
Несмотря на -1, указанный выше, я нашел эту ветку более обогащающей, чем другую ... это сила голосования.   -  person Marcelo Scofano Diniz    schedule 03.08.2020


Ответы (16)


Из раздела Выбор между свойствами и методами рекомендаций по проектированию для разработки библиотек классов:

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

person Ken Browning    schedule 02.03.2009
comment
Хотя я во многом согласен с этим, я не думаю, что часть о побочных эффектах правильная. Например, цвет часто является свойством объекта и имеет очевидные побочные эффекты (изменение цвета объекта). Изменение свойств имеет очевидный побочный эффект - изменение состояния объекта. - person Erik Funkenbusch; 02.03.2009
comment
Загадочный человек, меняющий цвет, - это желаемый эффект, а не побочный эффект. Побочный эффект - это то, на что не рассчитано основное действие. - person Muhammad Hasan Khan; 02.03.2009
comment
@Mystere Man: изменение цвета не является побочным эффектом, я полностью согласен с этим ответом - person Ahmed Said; 02.03.2009
comment
Потому что менее опытные разработчики считают, что недвижимость проще в использовании. - На мой взгляд, это единственная причина раскрывать недвижимость. Но я прав? - person Tsabo; 11.08.2011
comment
Как насчет изменения свойства AutoSize в элементе управления? Он также изменит Width и Heigth. Это тоже не побочный эффект? - person comecme; 17.12.2012
comment
@comecme Я бы сказал, что изменение AutoSize должно изменить Width и Height. Как сказал Хасан Хан, побочный эффект не предусмотрен. - person Brian J; 12.06.2013
comment
В чем разница во внутренней реализации свойства и метода. Помещается ли что-нибудь в стек вызовов всякий раз, когда используется свойство? Если нет, то как еще с этим справиться? - person Praveen; 17.07.2014
comment
Должна ли вещь IsValid быть свойством или полем в модели? - person Hooch; 21.01.2016
comment
Всегда упускают из виду то, ЧТО строится. Хороший дизайн API будет использовать свойства (автоматические геттеры и сеттеры) вместо методов для чистого интерфейса. В хорошем дизайне приложения будут использоваться методы, позволяющие избежать бесконечного набора шаблонов кода в пользу чистого прямого кода. - person Hal50000; 11.11.2016
comment
Я бы поспорил за свойства со сложным вычислением, если такое свойство можно привязать. Например, если вам нужно создать сложные многоразовые интерфейсы, может быть проще привязать к таким данным вместо кода для выполнения списка функций для получения таких данных. Так что о сложности речь не идет. Теперь, если вы имеете в виду время отклика, то я согласен. Доступ к собственности не займет много времени. - person visc; 05.02.2018

Да, если все, что вы делаете, это получение и настройка, используйте свойство.

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

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

Они в значительной степени взаимозаменяемы, но свойство сигнализирует пользователю, что реализация относительно "проста". Да, и синтаксис стал немного чище.

Вообще говоря, моя философия заключается в том, что если вы начнете писать имя метода, которое начинается с get или set и принимает ноль или один параметр (соответственно), то это главный кандидат на свойство.

person cletus    schedule 02.03.2009
comment
Проголосовали против. Это не так. Сложность геттера или сеттера инкапсулируется в коде геттера / сеттера. Насколько это сложно, не имеет значения вообще, равно как и то, влияет ли он на несколько элементов данных. Это правда, что нестандартные или множественные параметры потребуют метода, но в остальном этот ответ неточен. - person Hal50000; 11.11.2016
comment
Первое предложение все объясняет. Браво. - person SWIIWII; 23.09.2017

Свойства - это способ ввода или извлечения данных из объекта. Они создают абстракцию над переменными или данными внутри класса. Они аналогичны геттерам и сеттерам в Java.

Методы инкапсулируют операцию.

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

Я использую методы при создании операции, например, для получения данных из базы данных. Любая операция, в которой есть движущиеся части, является кандидатом на применение метода.

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

public Label Title 
{
   get{ return titleLabel;}
   set{ titleLabel = value;}
}

Установка текста:

Title.Text = "Properties vs Methods";

Если бы я устанавливал только свойство Text метки, я бы сделал это следующим образом:

public string Title 
{
   get{ return titleLabel.Text;}
   set{ titleLabel.Text = value;}
}

Установка текста:

Title = "Properties vs Methods";
person Chuck Conway    schedule 02.03.2009

Выполняя поиск в MSDN, я нашел ссылку на Свойства и методы, в котором приведены отличные рекомендации по созданию методов:

  • Операция представляет собой преобразование, например Object.ToString.
  • Операция достаточно дорогостоящая, поэтому вы хотите сообщить пользователю, что ему следует подумать о кешировании результата.
  • Получение значения свойства с помощью метода доступа get будет иметь заметный побочный эффект.
  • Вызов элемента дважды подряд дает разные результаты.
  • Порядок исполнения важен. Обратите внимание, что свойства типа должны иметь возможность устанавливаться и извлекаться в любом порядке.
  • Член статичен, но возвращает значение, которое можно изменить.
  • Член возвращает массив. Свойства, возвращающие массивы, могут вводить в заблуждение. Обычно необходимо вернуть копию внутреннего массива, чтобы пользователь не мог изменить внутреннее состояние. Это, в сочетании с тем фактом, что пользователь может легко предположить, что это индексированное свойство, приводит к неэффективному коду.
person Gavin Miller    schedule 29.06.2009
comment
Я согласен с тем, что это имеет смысл везде, где это применимо. Но прав ли я, что использование свойств через привязку XAML в WPF не оставляет выбора, кроме выполнения соответствующих действий в установщике? (особенно после нового SelectedItem для ComboBoxes, ListBoxes и т. д.) - person Nicolas; 30.10.2018

Если вы устанавливаете фактическое свойство вашего объекта, вы используете свойство.

Если вы выполняете задачу / функцию, вы используете метод.

В вашем примере это определенное свойство.

Если, однако, ваша функциональность связана с AppendToLabel, вы должны использовать метод.

person Robin Day    schedule 02.03.2009

Симантически свойства - это атрибуты ваших объектов. Методы - это поведение вашего объекта.

Ярлык - это атрибут, и имеет смысл сделать его свойством.

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

Автомобиль {цвет, модель, марка}

У автомобиля есть атрибуты Color, Model и Brand, поэтому нет смысла иметь метод SetColor или SetModel, потому что мы симантически не просим Car установить свой собственный цвет.

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

person Muhammad Hasan Khan    schedule 02.03.2009

Достаточно посмотреть на само название ... «Собственность». Что это означает? Словарь определяет это по-разному, но в этом случае лучше всего подходит «существенный или отличительный признак или качество вещи».

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

Свойства на самом деле являются функциями. Все они компилируются в getXXX () и setXXX (). Он просто скрывает их в синтаксическом сахаре, но он придает семантическое значение процессу.

Подумайте о свойствах как о атрибутах. У машины много атрибутов. Цвет, MPG, Модель и т. Д. Не все свойства настраиваются, некоторые можно рассчитать.

Между тем Метод - это действие. GetColor должен быть свойством. GetFile () должен быть функцией. Другое практическое правило: если он не меняет состояние объекта, то это должна быть функция. Например, CalculatePiToNthDigit (n) должен быть функцией, потому что он фактически не изменяет состояние объекта Math, к которому он прикреплен.

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

person Erik Funkenbusch    schedule 02.03.2009

Свойства должны быть только простыми и иметь одни вкладыши. Что-нибудь еще, и это действительно следует переместить в метод. Сложный код всегда должен быть в методах.

person Neil Bostrom    schedule 02.03.2009

Я использую свойства только для доступа к переменным, т.е. получения и установки отдельных переменных или получения и настройки данных в элементах управления. Как только требуется / выполняется какое-либо манипулирование данными, я использую методы.

person Marcus L    schedule 02.03.2009

С точки зрения дизайна, свойства представляют данные или атрибуты объекта класса, а методы - действия или поведение объекта класса.

В .Net, world есть и другие последствия использования свойств:

  • Свойства используются в привязке данных, а методы get_ / set_ - нет.
  • Свойства пользователя сериализации XML как естественный механизм сериализации.
  • Доступ к свойствам осуществляется с помощью PropertyGrid и внутренний ICustomTypeDescriptor , который можно эффективно использовать, если вы пишете собственную библиотеку.
  • Свойства контролируются Атрибутами. , его можно использовать с умом для разработки программного обеспечения, ориентированного на аспект.

Заблуждения (ИМХО) об использовании Недвижимости:

  • Используется для отображения небольших вычислений: Блок Get ControlDesigner.SelectionRules занимает 72 строки !!
  • Используется для раскрытия внутренних структур данных: даже если свойство не сопоставляется с внутренним элементом данных, его можно использовать как свойство, если оно является атрибутом вашего класса. И наоборот, даже если его атрибут свойств вашего класса не рекомендуется, возвращать массив, такой как элементы данных (вместо этого используются методы для возврата глубокой копии элементов).

В приведенном здесь примере это могло быть написано с большим деловым значением как:

public String Title
{
    set { Label.Text = text; }
}
person NileshChauhan    schedule 02.03.2009

Еще большим плюсом для Properties является то, что значение свойства можно увидеть в Visual Studio во время отладки.

person David Karlaš    schedule 04.10.2013
comment
Это приятная функция, но неточная, если свойство имеет сложные побочные эффекты, такие как изменение записи в базе данных на get. Когда последовательные вызовы свойства возвращают разные результаты, этот код действительно должен быть методом. - person AlainD; 12.05.2021

Я предпочитаю использовать свойства для методов добавления / установки с параметром 1. Если параметров больше, используйте методы.

person abatishchev    schedule 02.03.2009

Свойства действительно хороши, потому что они доступны в визуальном дизайнере Visual Studio, если у них есть доступ.

Они используются, если вы просто устанавливаете и получаете и, возможно, некоторую проверку, которая не имеет доступа к значительному количеству кода. Будьте осторожны, потому что создать сложные объекты во время проверки непросто.

Любые другие методы являются предпочтительными.

Дело не только в семантике. Использование неподходящих свойств вызывает странности в визуальном дизайнере Visual Studio.

Например, я получал значение конфигурации в свойстве класса. Класс конфигурации фактически открывает файл и запускает запрос sql, чтобы получить значение этой конфигурации. Это вызвало проблемы в моем приложении, когда файл конфигурации открывался и блокировался самой Visual Studio, а не моим приложением, потому что не только читал, но и записывал значение конфигурации (через метод установки). Чтобы исправить это, мне просто пришлось изменить его на метод.

person Jeremy Edwards    schedule 02.03.2009

Вот хороший набор рекомендаций о том, когда использовать свойства и методы из Билл Вагнер

  • Используйте свойство, когда все это верно: методы получения должны быть простыми и, таким образом, вряд ли будут генерировать исключения. Обратите внимание, что это подразумевает отсутствие доступа к сети (или базе данных). Любой из них может выйти из строя и, следовательно, вызвать исключение.
  • У них не должно быть зависимости друг от друга. Обратите внимание, что это будет включать установку одного свойства и его влияние на другое. (Например, установка свойства FirstName повлияет на доступное только для чтения свойство FullName, которое состоит из свойств имя + фамилия, подразумевает такую ​​зависимость)
  • Их следует устанавливать в любом порядке.
  • Получатель не имеет наблюдаемого побочного эффекта. Обратите внимание, что это руководство не исключает некоторых форм ленивого вычисления свойства.
  • Метод всегда должен возвращаться немедленно. (Обратите внимание, что это исключает свойство, которое выполняет вызов доступа к базе данных, вызов веб-службы или другую аналогичную операцию).
  • Используйте метод, если член возвращает массив.
  • Повторные вызовы геттера (без промежуточного кода) должны возвращать то же значение.
  • Повторные вызовы установщика (с тем же значением) не должны отличаться от одного вызова.

  • Get не должен возвращать ссылку на внутренние структуры данных (см. Пункт 23). Метод может вернуть полную копию и может избежать этой проблемы.

* Взято из моего ответа на повторяющийся вопрос.

person Chris Ballance    schedule 13.08.2012
comment
Самые популярные и принятые ответы здесь stackoverflow.com/a/1294189/1551 Почему голосование против? - person Chris Ballance; 24.02.2016
comment
Я понимаю, что немного опоздал на вечеринку, но это отрицательное голосование, скорее всего, произошло из-за того, что вы скопировали свой ответ. Копируя вставку, вы признали, что этот вопрос был в основном дубликатом другого. Таким образом, вы должны были пометить его как дубликат вместо того, чтобы отвечать на него. Я рекомендую посмотреть статью о Meta, чтобы узнать, как должны повторяться вопросы. быть обработанным. - person JoshuaTheMiller; 11.10.2017

Это просто.

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

2: Используйте метод, когда вы хотите выполнить какое-либо действие, например, вы предоставляете некоторые данные в качестве параметра, а ваш метод выполняет некоторую обработку на основе предоставленных значений и возвращает обработанное значение в качестве вывода. Или вы хотите изменить значение какого-либо поля этим вычислением. «Таким образом, метод представляет собой действие».

person Community    schedule 07.02.2019

Я пришел из Java и какое-то время использовал метод get .. set ...

Когда я пишу код, я не спрашиваю себя: «Доступ к этим данным прост или требует сложного процесса?» потому что все может измениться (сегодня получить это свойство просто, для создания нового может потребоваться какой-то или тяжелый процесс).

Сегодня у меня есть метод SetAge (int age) tomonrow, у меня также будет метод SetAge (date Birthdate), который вычисляет возраст, используя дату рождения.

Я был очень разочарован тем, что свойство преобразования компилятора в get и set, но не считает мои методы Get ... и Set .. одинаковыми.

person Marco Staffoli    schedule 30.06.2010