Властивості та методи


135

Швидке запитання: Коли ви вирішили використовувати властивості (в C #) і коли ви вирішили використовувати методи?

Ми зайняті цією дискусією і знайшли деякі сфери, де можна обговорити, чи варто використовувати властивість чи метод. Один з таких прикладів:

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

У прикладі Label- це елемент керування на сторінці ASPX. Чи існує принцип, який може керувати рішенням (в даному випадку), чи зробити це методом чи властивістю.

Я прийму відповідь, яка є найбільш загальною та всеосяжною, але це стосується і прикладу, який я наводив.


2
-1 на це питання було задано і відповіли раніше: stackoverflow.com/questions/164527/…
Елемент

Плюси і мінуси методу / поля / властивості можуть породжувати тривалі дебати; деяке загальне використання для властивостей: коли ви хочете приватні / захищені поля, але в той же час ви хочете їх виставити. Інше використання - мати не тільки заяви, але й вирази (дії, якщо вам подобається) навіть if()перевірки (відповідно до MSDN). Але це складно, оскільки користувач не завжди знає про вартість обробки доступу до змінної (властивості) (тобто код недоступний), і з міркувань строгості потрібно було б орієнтувати властивість. О, і "бонус", ви не можете використовувати вказівники з властивостями.
mireazma

Відповіді:


145

З розділу " Вибір між властивостями та методами " Правила проектування для розробки бібліотек класів:

Загалом, методи представляють дії, а властивості представляють дані. Властивості мають використовуватися як поля, тобто властивості не повинні бути обчислювально складними або створювати побічні ефекти. Якщо це не порушує наведені нижче вказівки, варто скористатися властивістю, а не методом, оскільки менш досвідчені розробники вважають властивості простішими у використанні.


3
Хоча я багато з цим погоджуюся, я не вважаю, що частина побічних ефектів є правильною. Наприклад, "Колір" часто є властивістю об'єкта, і він має очевидні побічні ефекти (зміна кольору об'єкта). Зміна властивостей має очевидний побічний ефект зміни стану об'єкта.
Ерік Функенбуш

46
Mystere Man змінює колір - це бажаний ефект, а не побічний ефект. Побічний ефект - це те, що не призначене для первинної дії.
Мухаммед Хасан Хан

2
@Mystere Man: визначити, що зміна кольору не є побічним ефектом, я повністю погоджуюся з цією відповіддю
Ахмед Саїд

2
"Тому що менш досвідчені розробники знаходять властивості простішими у використанні." - Як я бачу, це єдина причина піддавати властивості. Але я маю рацію?
Цабо

2
Чим відрізняється внутрішня реалізація властивості від методу. Чи що-небудь штовхається в стек викликів кожного разу, коли використовується властивість? Якщо ні, то як інакше це обробляється?
Praveen

57

Так, якщо все, що ви робите, це отримання та налаштування, використовуйте властивість.

Якщо ви робите щось складне, що може вплинути на декілька членів даних, метод є більш підходящим. Або якщо ваш геть приймає параметри або ваш сетер приймає більше, ніж параметр значення.

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

Вони багато в чому взаємозамінні, але властивість сигналізує користувачеві про те, що реалізація є відносно "простою". О, і синтаксис трохи чистіший.

Взагалі кажучи, моя філософія полягає в тому, що якщо ви починаєте писати ім'я методу, яке починається з get або set і приймає нуль або один параметр (відповідно), то це головний кандидат для властивості.


1
Проголосований. Це неправильно. Складність геттера або сеттера інкапсульована в коді геттера / сеттера. Наскільки складний він взагалі не доречний, і чи він "впливає на декілька членів даних" Це правда, що для нестандартних або декількох параметрів потрібен метод, але в іншому випадку ця відповідь не є точною.
Hal50000

Перше речення пояснює все. Браво.
SWIIWII

13

Властивості - це спосіб введення або отримання даних з об'єкта. Вони створюють абстракцію над змінними або даними в класі. Вони аналогічні геттерам і сетерам на Яві.

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

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

Я використовую методи, коли створюю операцію, як отримання даних із бази даних. Будь-яка операція, яка має рухомі частини, є кандидатом у спосіб.

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

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 не залишає іншого вибору, ніж виконання відповідних дій у сеттері? (особливо після нового Вибраного тексту для комбо-боксів, списків, тощо)
Ніколас

9

Потрібно лише подивитися на саму назву ... "Власність". Що це означає? Словник визначає його багатьма способами, але в цьому випадку "найкращий або відмінний атрибут або якість речі" найкраще підходить.

Подумайте про мету дії. Насправді ви змінюєте чи отримуєте "важливий чи відмітний атрибут"? У вашому прикладі ви використовуєте функцію для встановлення властивості текстового поля. Це здається дурним, чи не так?

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

Подумайте про такі властивості, як атрибути. Автомобіль має багато атрибутів. Колір, MPG, модель тощо. Не всі властивості можна встановити, деякі можна обчислити.

Тим часом метод - це дія. GetColor має бути власністю. GetFile () має бути функцією. Ще одне правило - якщо воно не змінює стан об'єкта, то це має бути функцією. Наприклад, CalculatePiToNthDigit (n) має бути функцією, оскільки це насправді не змінює стан об'єкта Math, до якого він приєднаний.

Це, можливо, трохи суперечить, але це дійсно зводиться до вирішення, які ваші об’єкти і що вони представляють. Якщо ви не можете зрозуміти, чи це має бути властивість чи функція, можливо, неважливо, яка.


9

Символічно властивості - це атрибути ваших об'єктів. Методи - це поведінка вашого об’єкта.

Мітка - це атрибут, і має сенс зробити його властивістю.

З точки зору об’єктно-орієнтованого програмування ви повинні чітко розуміти, що є частиною поведінки, а що лише атрибутом.

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

Автомобіль має атрибути Color, Model та Brand, тому не має сенсу використовувати метод SetColor або SetModel, оскільки символічно ми не просимо Car встановити свій власний колір.

Тож якщо ви зіставите випадок властивості / методу в об’єкт реального життя або подивитесь на нього з точки зору симматичного погляду, ваше плутанина дійсно пройде.


4

Також великим плюсом для властивостей є те, що значення властивості можна побачити в Visual Studio під час налагодження.


3

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


3

Властивості повинні бути встановлені просто, і отримати один вкладиш. Більше нічого, і це дійсно слід перенести на метод. Складний код завжди повинен бути у методах.


3

Я використовую властивості лише для змінного доступу, тобто отримання та встановлення окремих змінних або отримання та встановлення даних у елементах управління. Як тільки будь-який вид обробки даних потрібен / виконується, я використовую методи.


3

Що стосується дизайну Властивості представляють Дані або Атрибути об'єкта класу, а методи - дії або поведінки об'єкта класу.

У .Net, світі є й інші наслідки використання властивостей:

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

Помилкові уявлення (IMHO) щодо використання властивостей:

  • Використовується для викриття невеликих обчислень: Блок отримання ControlDesigner.SelectionRules працює в 72 рядки !!
  • Використовується для викриття внутрішніх структур даних: Навіть якщо властивість не відображається до внутрішнього члена даних, ви можете використовувати його як властивість, якщо це атрибут вашого класу. Viceversa, навіть якщо його атрибут властивостей вашого класу небажаний, повертати масив, як члени даних (натомість методи використовуються для повернення глибокої копії членів.)

У прикладі тут це могло бути написано з більш діловим значенням:

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

2

Властивості справді приємні, оскільки вони доступні у візуальному дизайнері візуальної студії за умови, що вони мають доступ.

Вони, як правило, використовуються, якщо ви просто встановлюєте та отримуєте і, можливо, деяку перевірку, яка не отримує доступ до значної кількості коду. Будьте уважні, тому що створювати складні об'єкти під час перевірки не просто.

Будь-які інші методи є кращим способом.

Справа не лише в семантиці. Використання властивостей, невідповідних починати дивакувати, виникає у візуальному дизайнері візуальної студії.

Наприклад, я отримував значення конфігурації у властивості класу. Клас конфігурації фактично відкриває файл і виконує запит sql, щоб отримати значення цієї конфігурації. Це спричинило проблеми в моєму додатку, коли файл конфігурації буде відкритий і заблокований самою візуальною студією, а не моїм додатком, оскільки він не тільки читав, але записував значення конфігурації (методом setter). Щоб виправити це, я просто повинен був змінити його на метод.


1

Ось хороший набір вказівок щодо використання властивостей проти методів Білла Вагнера

  • Використовуйте властивість, коли все це відповідає дійсності. Отриманці повинні бути простими і, таким чином, навряд чи викидати винятки. Зауважте, що це означає відсутність доступу до мережі (або бази даних). Або не може, і тому кине виняток.
  • Вони не повинні мати залежностей один від одного. Зауважте, що це включатиме встановлення однієї властивості та вплив на іншу. (Наприклад, встановлення властивості FirstName вплине на властивість FullName лише для читання, що складається з властивостей імені + прізвища, передбачає таку залежність)
  • Вони повинні бути встановлені в будь-якому порядку
  • У геттера немає спостережуваного побічного ефекту. Примітка. Це керівництво не виключає деяких форм лінивої оцінки властивості.
  • Метод повинен завжди повертатися негайно. (Зверніть увагу, що це виключає властивість, яка робить виклик доступу до бази даних, виклик веб-служби чи інша аналогічна операція).
  • Використовуйте метод, якщо член повертає масив.
  • Повторні дзвінки до геттера (без втручання коду) повинні повертати те саме значення.
  • Повторні дзвінки до сектора (з однаковим значенням) не повинні відрізнятися від одного виклику.

  • Отримання не повинно повертати посилання на внутрішні структури даних (Див. Пункт 23). Метод може повернути глибоку копію і міг уникнути цієї проблеми.

* Взяте з моєї відповіді на повторне запитання.


З найвищим рейтингом і приймаються відповіді тут stackoverflow.com/a/1294189/1551 Чому downvote?
Кріс Баланс

2
Я усвідомлюю, що я трохи спізнююся на вечірку, але цей голос, швидше за все, стався через те, що ви копіювали свою відповідь. Копіюючи вставлення, ви визнали, що це питання в основному є дублікатом іншого. Як такий, ви повинні позначити його як дублікат, а не відповідати на нього. Рекомендую переглянути статтю про Meta щодо того, як слід обробляти повторювані питання.
Джошуа

0

Це просто.

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

2: Використовуйте метод, коли ви хочете виконати якусь дію, як, наприклад, ви подаєте деякі дані як параметр, а ваш метод виконує деяку обробку на основі наданих значень і повертає оброблене значення як вихід. Або ви хочете змінити значення деякого поля за допомогою цього обчислення. "Таким чином метод являє собою дію".


-1

Я родом з Java, я використовував метод get .. set .. на деякий час.

Коли я пишу код, я не запитую себе: "доступ до цих даних простий або вимагає важкого процесу?" тому що все може змінитися (сьогодні відновити цю властивість просто, для того, щоб завдати це, потрібен певний або важкий процес).

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.