Вопрос

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

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

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

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

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

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

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Операция представляет собой преобразование, например Object.ToString.
  • Операция достаточно дорогой, чтобы вы хотели передать пользователю, чтобы они рассмотрели кэширование результата.
  • Получение значения свойства с использованием доступа GET будет иметь наблюдаемый побочный эффект.
  • Вызов члена дважды подряд приводит к разным результатам.
  • Порядок выполнения важен.Обратите внимание, что свойства типа должны быть установлены и извлечены в любом порядке.
  • Член является статическим, но возвращает значение, которое можно изменить.
  • Член возвращает массив.Свойства, которые возвращают массивы, могут быть очень вводящими в заблуждение.Обычно необходимо вернуть копию внутреннего массива, чтобы пользователь не мог изменить внутреннее состояние.Это в сочетании с тем фактом, что пользователь может легко предположить, что это индексированное свойство, приводит к неэффективному коду.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

public String Title
{
    set { Label.Text = text; }
}

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

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

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

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

Это просто.

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

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

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

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

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

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

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