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

135

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

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

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

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

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

Trumpi
источник
2
-1 этот вопрос был задан и получен ответ ранее: stackoverflow.com/questions/164527/…
Элемент
Метод / поле / свойство плюсы и минусы могут вызвать длительные дебаты; какое-то общее использование для свойств: когда вы хотите закрытые / защищенные поля, но в то же время хотите открыть их. Другое использование состоит в том, чтобы иметь не только операторы, но и выражения (действия, если хотите), даже if()проверки (согласно MSDN). Но это сложно, поскольку пользователь не всегда осознает стоимость обработки доступа к переменной (свойству) (т. Е. Код недоступен), и по соображениям строгости нужно будет сравнить свойство. Да, и «бонус», вы не можете использовать указатели со свойствами.
Миреазма

Ответы:

146

Из раздела « Выбор между свойствами и методами » Руководства по разработке библиотек классов:

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

Кен Браунинг
источник
3
Хотя я согласен со многим из этого, я не думаю, что часть о побочных эффектах является правильной. Например, «Цвет» часто является свойством объекта и имеет очевидные побочные эффекты (изменение цвета объекта). Изменение свойств имеет очевидный побочный эффект изменения состояния объекта.
Эрик Фанкенбуш
46
Mystere Man изменение цвета является желаемый эффект, а не побочный эффект. Побочный эффект - это то, что не предназначено в основном действии.
Мухаммед Хасан Хан
2
@Mystere Man: определенное изменение цвета не является побочным эффектом, я полностью согласен с этим ответом
Ахмед Саид
2
«Потому что менее опытные разработчики находят свойства проще в использовании». - На мой взгляд, это единственная причина выставить недвижимость. Но я прав?
Цабо
2
В чем отличие внутренней реализации свойства от метода. Что-нибудь выталкивается в стек вызовов всякий раз, когда используется свойство? Если нет, то как еще это обрабатывается?
Правин
57

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

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

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

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

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

Клетус
источник
1
Вниз проголосовали. Это не правильно. Сложность метода получения или установки заключена в коде получения / установки. Насколько сложный он вообще не важен и не влияет ли он на «несколько элементов данных». Это правда, что для нестандартных или нескольких параметров потребуется метод, но в противном случае этот ответ не является точным.
Hal50000
Первое предложение объясняет все. Браво.
SWIIWII,
13

Свойства - это способ ввода или извлечения данных из объекта. Они создают абстракцию над переменными или данными внутри класса. Они аналогичны геттерам и сеттерам в 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";
Чак Конвей
источник
12

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

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

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

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

Робин Дэй
источник
11

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

  • Операция конвертации, например Object.ToString.
  • Операция достаточно дорогая, и вы хотите сообщить пользователям, что они должны рассмотреть возможность кэширования результата.
  • Получение значения свойства с использованием метода доступа get будет иметь видимый побочный эффект.
  • Повторный вызов участника дважды приводит к разным результатам.
  • Порядок исполнения важен. Обратите внимание, что свойства типа должны быть в состоянии быть установлены и извлечены в любом порядке.
  • Член является статическим, но возвращает значение, которое можно изменить.
  • Член возвращает массив. Свойства, которые возвращают массивы, могут вводить в заблуждение. Обычно необходимо вернуть копию внутреннего массива, чтобы пользователь не мог изменить внутреннее состояние. Это в сочетании с тем, что пользователь может легко предположить, что это индексированное свойство, приводит к неэффективному коду.
Гэвин Миллер
источник
Я согласен, что это имеет смысл везде, где это применимо. Но прав ли я, что использование свойств через связывание XAML в WPF не оставляет выбора, кроме как выполнять соответствующие действия в установщике? (особенно на новый SelectedItem для ComboBox, ListBoxes и т. д.)
Николас
9

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

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

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

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

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

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

Эрик Фанкенбуш
источник
9

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

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

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

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

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

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

Мухаммед Хасан Хан
источник
4

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

Дэвид Карлаш
источник
3

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

abatishchev
источник
3

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

Нил Бостром
источник
3

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

Маркус Л
источник
3

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

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

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

Заблуждения (IMHO) об использовании свойств:

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

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

public String Title
{
    set { Label.Text = text; }
}
NileshChauhan
источник
2

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

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

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

Это не только семантика. Использование неуместных свойств может привести к появлению странностей в визуальном дизайнере визуальной студии.

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

Джереми Эдвардс
источник
1

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

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

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

* Взято из моего ответа на дубликат вопроса.

Крис Балланс
источник
Самые рейтинговые и принятые ответы здесь stackoverflow.com/a/1294189/1551 Почему понижающий голос?
Крис Балланс
2
Я понимаю, что немного опоздал на вечеринку, но, скорее всего, это произошло из-за того, что вы скопировали свой ответ. Вставив копию, вы признали, что этот вопрос в основном повторял другой. Таким образом, вы должны были пометить его как дубликат, а не отвечать на него. Я рекомендую посмотреть на статью о Meta, чтобы узнать, как обрабатывать дубликаты вопросов.
Джошуа
0

Это просто

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

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

Марсианин
источник
-1

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

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

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

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

Марко Стаффоли
источник