Чому я повинен уникати використання властивостей у C #?


102

У своїй чудовій книзі CLR Via C # Джефрі Ріхтер сказав, що йому не подобаються властивості, і рекомендує не користуватися ними. Він чомусь дав, але я не дуже розумію. Хтось може мені пояснити, чому я повинен чи не повинен використовувати властивості? У C # 3.0, з автоматичними властивостями, це змінюється?

В якості довідки я додав думку Джеффрі Ріхтера:

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

• метод властивості може кинути виняток; доступ до поля ніколи не кидає виняток.

• Властивість не може бути передана методу як вихід або ref; поле може. Наприклад, наступний код не компілюється:

using System;
public sealed class SomeType
{
   private static String Name 
   {
     get { return null; }
     set {}
   }
   static void MethodWithOutParam(out String n) { n = null; }
   public static void Main()
   {
      // For the line of code below, the C# compiler emits the following:
      // error CS0206: A property or indexer may not
      // be passed as an out or ref parameter
      MethodWithOutParam(out Name);
   }
}

• метод власності може зайняти багато часу; доступ до поля завжди завершується негайно. Загальною причиною використання властивостей є виконання синхронізації потоків, яка може зупинити потік назавжди, а отже, властивість не повинна використовуватися, якщо потрібна синхронізація потоку. У цій ситуації кращим є метод. Крім того, якщо до вашого класу можна отримати доступ віддалено (наприклад, ваш клас походить від System.MashalByRefObject), виклик методу властивості буде дуже повільним, а отже, метод надає перевагу властивості. На мою думку, класи, похідні від MarshalByRefObject, ніколи не повинні використовувати властивості.

• Якщо викликається кілька разів поспіль, метод властивості може кожен раз повертати інше значення; поле щоразу повертає те саме значення. Клас System.DateTime має властивість readonly Now, яка повертає поточну дату та час. Кожен раз, коли ви запитуєте цей ресурс, він повертає інше значення. Це помилка, і Microsoft бажає, щоб вони могли виправити клас, зробивши метод замість властивості.

• Метод властивості може спричинити помітні побічні ефекти; доступ до поля ніколи не відбувається. Іншими словами, користувач типу повинен мати можливість встановлювати різні властивості, визначені типом, у будь-якому обраному ним порядку, не помічаючи різної поведінки у типі.

• метод властивості може вимагати додаткової пам'яті або повернути посилання на те, що насправді не є частиною стану об'єкта, тому зміна повернутого об'єкта не впливає на вихідний об'єкт; запит на поле завжди повертає посилання на об'єкт, який гарантовано є частиною початкового стану об'єкта. Робота з властивістю, яка повертає копію, може бути дуже заплутаною для розробників, і ця характеристика часто не задокументована.


11
Я є власником 3-го видання "CLR via C #", а на сторінці 242 містер Ріхтер говорить, що він особисто не любить властивості, але ніколи не рекомендує їх використовувати. Будь ласка, цитуйте версію книги та номер сторінки, де ви це читали.
kirk.burleson

Відповіді:


173

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

Особисто я не погоджуюся з ним з цього питання - я вважаю, що властивості роблять код клієнта набагато простішим для читання, ніж еквівалентний метод дзвінків. Я погоджуюся, що розробникам потрібно знати, що властивості - це в основному методи маскування - але я думаю, що навчити розробників про це краще, ніж зробити код важче читати за допомогою методів. (Зокрема, побачивши код Java з кількома геттерами та сеттерами, що викликаються одним і тим же твердженням, я знаю, що еквівалентний код C # був би набагато простішим для читання. Закон Деметера в теорії все дуже добре, але іноді foo.Name.Lengthнасправді є правильне використання ...)

(І ні, автоматично реалізовані властивості насправді нічого з цього не змінюють.)

Це трохи схоже на аргументи проти використання методів розширення - я можу зрозуміти міркування, але практична користь (при використанні несильно) переважає меншу сторону, на мій погляд.


Дякую за вашу відповідь! Про аргументи проти використання методів розширення: ви говорите про якусь тему Джефрі Ріхтера чи абстрактно?
абатищев

@abatishchev: Це був просто загальний пункт щодо методів розширення. Це не пов'язано безпосередньо з властивостями.
Джон Скіт

Я б пішов далі. За винятком аспекту продуктивності, я не розумію, чому програміст повинен знати, якщо щось є полем або властивістю. Він повинен розглядати це як атрибут екземпляра, що позначає ДЕРЖАВНИЙ Екземпляр об'єкта, і реалізація об'єкта повинна піклуватися про всі зміни його стану (в рамках контракту класу). Таким чином, властивості також можуть бути полями в одних випадках або стати полями в інших, якщо, можливо, перероблений дизайн класу. Тоді, вирішення між полем або власністю - питання про те, наскільки захист потребує держава, щоб залишатися послідовною.
TheBlastOne

1
@PatrickFromberg: Ви, мабуть, пропустили велику кількість коду, який використовує поля лише для читання. Нічого не можна сказати, що властивості передбачають незмінність. У мене часто є поля лише для читання, що підтримують властивості лише для читання - ви вважаєте, це погано?
Джон Скіт

1
@Patrick: Ні, це приносить користь відокремленню API від реалізації - ви згодом можете змінити спосіб обчислення властивості з поля (наприклад, для обчислення двох пов’язаних властивостей з одного поля).
Джон Скіт

34

Що ж, давайте розбираємо його аргументи один за одним:

Властивість може бути лише для читання або лише для запису; доступ до поля завжди читабельний і доступний для запису.

Це виграш для властивостей, оскільки у вас є більш тонкий контроль доступу.

Метод властивості може кинути виняток; доступ до поля ніколи не кидає виняток.

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

• Властивість не може бути передана методу як вихід або ref; поле може.

Справедливий.

• метод власності може зайняти багато часу; доступ до поля завжди завершується негайно.

Це також може зайняти дуже мало часу.

• Якщо викликається кілька разів поспіль, метод властивості може кожен раз повертати інше значення; поле щоразу повертає те саме значення.

Неправда. Звідки ви знаєте, що значення поля не змінилося (можливо, іншим потоком)?

Клас System.DateTime має властивість readonly Now, яка повертає поточну дату та час. Кожен раз, коли ви запитуєте цей ресурс, він повертає інше значення. Це помилка, і Microsoft бажає, щоб вони могли виправити клас, зробивши метод замість властивості.

Якщо це помилка, це другорядна.

• Метод властивості може спричинити помітні побічні ефекти; доступ до поля ніколи не відбувається. Іншими словами, користувач типу повинен мати можливість встановлювати різні властивості, визначені типом, у будь-якому обраному ним порядку, не помічаючи різної поведінки у типі.

Справедливий.

• метод властивості може вимагати додаткової пам'яті або повернути посилання на те, що насправді не є частиною стану об'єкта, тому зміна повернутого об'єкта не впливає на вихідний об'єкт; запит на поле завжди повертає посилання на об'єкт, який гарантовано є частиною початкового стану об'єкта. Робота з властивістю, яка повертає копію, може бути дуже заплутаною для розробників, і ця характеристика часто не задокументована.

Більшість протестів можна сказати і для язиків та сеттерів Java - і у нас їх було досить довго без таких проблем на практиці.

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


3
"проблеми можна вирішити шляхом кращого підкреслення синтаксису" : Як часто ви використовуєте загальнодоступні поля? Приватні поля зазвичай мають інший стиль, наприклад _field. Або просто ще малі літери field.
Стівен Євріс

18

Я не читав книгу, і ви не цитували її частини, яку ви не розумієте, тому мені доведеться здогадуватися.

Деякі люди не люблять властивості, тому що вони можуть змусити ваш код робити дивовижні речі.

Якщо я напишу Foo.Bar, люди, які її читають, зазвичай очікують, що це просто доступ до поля-члена класу Foo. Це дешева, майже безкоштовна операція, і це детерміновано. Я можу викликати це знову і знову і отримувати однаковий результат кожного разу.

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

Це аналогічний аргумент, чому Лінус ненавидить C ++. Ваш код може здивувати читача. Він ненавидить перевантаження оператора: a + bне обов'язково означає просте додавання. Це може означати надзвичайно складну операцію, як і властивості C #. Це може мати побічні ефекти. Це може зробити що завгодно.

Чесно кажучи, я думаю, що це слабкий аргумент. Обидві мови переповнені подібними речами. (Чи слід також уникати перевантаження оператора в C #? Зрештою, той же аргумент може бути використаний і там)

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

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

Однак у мене є ще одна причина вважати їх менш ніж ідеальними. Їх не можна передавати посиланням на інші функції.

Поля можна передавати як ref, що дозволяє викликаній функції отримувати прямий доступ до неї. Функції можна передавати як делегати, дозволяючи викликаної функції отримувати доступ до неї безпосередньо.

Властивості ... не може.

Це смокче.

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


3
Мій аргумент полягає в тому, що ви не повинні вважати, що це поле для початку - адже, якщо ви називаєте його з будь-якого іншого класу, ви все одно не повинні мати доступ до непостійних полів, оскільки вони повинні бути приватними. (Існує також угода про іменування, щоб повідомити вас.)
Джон Скіт

1
Так, я згоден. Аргумент, схоже, зводиться до того, що "я звик до цього синтаксису, який використовується виключно для полів. Тому поширити його на інші випадки погано". І очевидна відповідь: «Ну, звикніть, що тоді він охоплює інші випадки, і це буде не погано». ;)
jalf

Я хотів би, щоб мови .net забезпечували стандартний спосіб, за допомогою якого клас має властивості як refпарами; член (наприклад Foo) форми void Foo<T>(ActionByRef<Point,T> proc, ref T param)зі спеціальним атрибутом, і компілятор перетворюється thing.Foo.X+=someVar;на Foo((ref Point it, ref int param)=>it.X += param, ref someVar);. Оскільки лямбда є статичним делегатом, закриття не потрібно, і користувач об'єкта зможе використовувати будь-яке місце зберігання, яке підтримувало властивість як справжній refпараметр (і міг передати його іншим методам як refпараметр).
supercat

Виписування лямбда вручну створює дійсно прискіпливий вигляд вихідного коду, але саме тому, компілятор виконує перетворення було б корисно. Код для класу для викриття властивості "зворотний виклик за посиланням" був би досить розумним. Код некрасивий (відсутня трансформація) на стороні виклику.
supercat

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

17

Ще в 2009 році ця порада просто здавалася руйнуванням сорту « Хто перемістив мій сир» . Сьогодні це майже смішно застаріло.

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

Так, властивості можуть:

  • Вкажіть різні модифікатори доступу для геттера та сеттера. Це перевага перед полями. Поширений зразок - це мати публічний геттер і захищений або внутрішній сетер, дуже корисна методика успадкування, якої не можна досягти лише полями.

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

  • Виконати багато часу. Дійсне порівняння тут з методами , які займають однаково довго - не поля . Не випливає жодної підстави для твердження "переважний метод", окрім особистих переваг одного автора.

  • Повертайте різні значення від його отримувача при наступних виконаннях. Це майже здається жартом у такій близькості до точки, що висловлює чесноти ref/ outпараметрів із полями, значення поля після a ref/ outcall майже гарантовано відрізняється від його попереднього значення, і це непередбачувано.

    Якщо ми говоримо про конкретний (і практично академічний) випадок однопотокового доступу без афективних з’єднань, то досить добре розуміємо, що просто погана конструкція властивостей має побічні ефекти, що змінюються видимим станом, і, можливо, моя пам'ять зникає, але я просто не можу пригадати жодних прикладів людей, які використовують DateTime.Nowі очікують, що щоразу з'явиться однакове значення. Принаймні, не будь-які випадки, коли б вони не накрутили це так само погано з гіпотетичним DateTime.Now().

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

    Доступ до властивостей насправді може допомогти запобігти певним видам тимчасової зв'язку, примусивши об’єкт у дійсному стані до того, як будуть вжиті будь-які дії - наприклад, якщо у класу є а StartDateта ан EndDate, то встановлення значень " EndDateперед" StartDateможе також примусити StartDateназад. Це справедливо навіть у багатопотокових або асинхронних середовищах, включаючи очевидний приклад інтерфейсу, керованого подіями.

Інші речі, які можуть робити властивості, які поля не можуть включати:

  • Ледаче завантаження - один із найефективніших способів запобігання помилок ініціалізації порядку.
  • Сповіщення про зміни , які є майже всією основою архітектури MVVM .
  • Наслідування , наприклад, визначення абстрактних Typeчи Nameтак похідних класів може забезпечити цікаві, але, тим не менш, постійні метадані про себе.
  • Перехоплення , завдяки вищесказаному.
  • Індексатори , які кожен, кому коли-небудь доводилося працювати з COM-інтеропом, і неминуча кількість Item(i)викликів визнають чудовою річчю.
  • Робота з PropertyDescriptor, яка важлива для створення дизайнерів та для XAML-фреймів взагалі.

Ріхтер, безумовно, плідний автор і багато знає про CLR та C #, але мушу сказати, схоже, коли він спочатку написав цю пораду (я не впевнений, чи є це в його останніх редакціях - я щиро сподіваюся, що ні) що він просто не хотів відмовлятися від старих звичок і мав проблеми приймати конвенції C # (наприклад, C ++).

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

У C # є дві дуже сильні конвенції кодування з подібними умовами, якими поділяються інші мови CLR, і FXCop буде кричати на вас, якщо ви не будете дотримуватися їх:

  1. Поля завжди повинні бути приватними, ніколи не публічними.
  2. Поля повинні бути оголошені в camelCase. Властивості - PascalCase.

Таким чином, немає двозначності щодо того, чи Foo.Bar = 42є приналежністю до власності чи польовим аксесуаром. Це доступ до властивостей і до нього слід ставитися як до будь-якого іншого методу - він може бути повільним, він може кинути виняток і т. Д. Такий характер абстракції - цілком залежить від розсуду декларувального класу, як реагувати. Дизайнери класів повинні застосовувати принцип найменшого здивування, але абоненти не повинні припускати нічого про властивість, окрім того, що він робить те, що написано на бляшанці. Це цілеспрямовано.

Альтернативою властивостям є методи геттера / сеттера всюди. Це підхід Java, і це спорне з самого початку . Добре, якщо це ваша сумка, але це просто не те, як ми котимось у табір .NET. Ми намагаємось, принаймні, в межах статично типової системи уникати того, що Фоулер називає синтаксичним шумом . Ми не хочемо додаткових дужок, додаткових get/ setбородавок чи додаткових підписів методів - не, якщо ми можемо їх уникнути без втрати ясності.

Скажіть, що вам подобається, але foo.Bar.Baz = quux.Answers[42]читати завжди буде набагато простіше, ніж foo.getBar().setBaz(quux.getAnswers().getItem(42)). І коли ви читаєте тисячі рядків цього дня, це має значення.

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


11

Я не бачу причин, чому ви не повинні використовувати властивості взагалі.

Автоматичні властивості в C # 3+ лише трохи спрощують синтаксис (a la syntatic sugar).


будь ласка, прочитайте сторінки 215-216 цієї книги. Я впевнений, що ви знаєте, хто такий Джефрі Ріхтер!
Quan Mai

Я читав (CLR через C #, другий ред.), Не згоден з його позицією і не бачу реальних причин, не використовуйте властивості!
абатищев

Це гарна книга, але я не згоден з автором у цей момент.
Костянтин Таркус

Де саме це місце, де автор пропонує не використовувати властивості? Не знайшли нічого на с.215-217
Костянтин

Я додав думки Джефрі у своєму питанні :). Ви можете знайти його на сторінках 215-216 у друкованому виданні :)
Quan Mai

9

Це лише думка однієї людини. Я прочитав досить багато c # книг, і ще не бачив, щоб хтось говорив "не використовуй властивості".

Я особисто думаю, що властивості - одна з найкращих речей про c #. Вони дозволяють виставити стан за допомогою будь-якого механізму, який вам подобається. Ви можете лінь інстанціювати, коли вперше щось використовується, і ви можете перевірити встановлення значень і т. Д. Під час використання та запису їх я просто думаю про властивості як сеттери та геттери, що набагато приємніший синтаксис.

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

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

Напр

public class WorkerUsingMethod
{
   // Explicitly obvious that calculation is being done here
   public int CalculateResult()
   { 
      return ExpensiveLongRunningCalculation();
   }
}

public class WorkerUsingProperty
{
   // Not at all obvious.  Looks like it may just be returning a cached result.
   public int Result
   {
       get { return ExpensiveLongRunningCalculation(); }
   }
}

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

По-друге, і що ще важливіше, властивості можуть мати побічні ефекти, якщо оцінювати їх під час налагодження.

Скажіть, у вас є така властивість:

public int Result 
{ 
   get 
   { 
       m_numberQueries++; 
       return m_result; 
   } 
}

Тепер припустимо, у вас є виняток, який виникає, коли надто багато запитів зроблено. Здогадайтесь, що станеться, коли ви починаєте налагоджувати та перевертати властивість у налагоджувачі? Погані речі. Уникайте цього робити! Переглядаючи властивість, змінюється стан програми.

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


6

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


+1 для чіткого підкреслення важливості "контракту" між клієнтом та майном класу.
TheBlastOne

6

Я не можу не вибрати деталі думок Джефрі Ріхтера:

Властивість може бути лише для читання або лише для запису; доступ до поля завжди читабельний і доступний для запису.

Неправильно: поля можуть бути позначені лише для читання, тому лише конструктор об'єкта може записувати на них.

Метод властивості може кинути виняток; доступ до поля ніколи не кидає виняток.

Неправильно: Реалізація класу може змінити модифікатор доступу поля з публічного на приватне. Спроба прочитати приватні поля під час виконання завжди призведе до виключення.


5

Я не згоден з Джефрі Ріхтером, але я можу здогадатися, чому він не любить властивості (я не читав його книги).

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

  • не відбувається трудомістка операція всередині власника / налаштування власності
  • одержувач властивості не має побічних ефектів (викликаючи його кілька разів, результат не змінює)

На жаль, я бачив властивості, які не так поводилися. Але проблема не в самих властивостях, а в людях, які їх реалізували. Тож це просто вимагає певної освіти.


1
+1, оскільки він підкреслює важливість чистого контракту. Маючи, здавалося б, властивість лише для читання, яка регулярно повертає інше значення для кожної посилання, є властивістю readwrite - воно просто пише не власне значення, а інші змінні екземпляра (прямо чи опосередковано). Це не поганий стиль, але він повинен бути задокументований (або бути неявною частиною договору).
TheBlastOne

4

Є час, коли я вважаю, що не використовую властивості, і це письмово. Net Compact Framework code. Компілятор CF JIT не здійснює таку ж оптимізацію, як настільний компілятор JIT і не оптимізує прості аксесуари властивостей, тому в цьому випадку додавання простого властивості спричиняє невелику кількість розмивання коду за допомогою публічного поля. Зазвичай це не буде проблемою, але майже завжди у світі компактних рамок ви проти обмежених обмежень пам’яті, тому навіть такі маленькі заощадження, як це, рахуються.


4

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

Я колись бачив властивість, що називається щось на зразок Клієнти, що внутрішньо відкривав позашляховий виклик до бази даних та читав список клієнтів. У коді клієнта було "for (int i to Customers.Count)", що викликало окремий виклик до бази даних про кожну ітерацію та доступ до обраного Клієнта. Це жахливий приклад, який демонструє принцип збереження властивості дуже легким - рідко більше, ніж внутрішній доступ до поля.

Один аргумент ЗА використання властивостей полягає в тому, що вони дозволяють перевірити встановлене значення. Інше полягає в тому, що значення властивості може бути похідним значенням, а не окремим полем, як TotalValue = кількість * кількість.


3

Особисто я використовую властивості лише при створенні простих методів get / set. Я відхиляюся від цього, коли дію до складних структур даних.


3

Аргумент передбачає, що властивості погані, оскільки вони схожі на поля, але можуть робити дивні дії. Це припущення обґрунтоване очікуванням програмістів .NET:

Властивості не схожі на поля. Поля мають вигляд властивостей.

• метод властивості може кинути виняток; доступ до поля ніколи не кидає виняток.

Отже, поле - це як властивість, яка гарантовано ніколи не кине виняток.

• Властивість не може бути передана методу як вихід або ref; поле може.

Отже, поле схоже на властивість, але воно має додаткові можливості: перехід до а ref/ outприйняття методів.

• метод власності може зайняти багато часу; доступ до поля завжди завершується негайно. [...]

Отже, поле - це як швидка властивість.

• Якщо викликається кілька разів поспіль, метод властивості може кожен раз повертати інше значення; поле щоразу повертає те саме значення. Клас System.DateTime має властивість readonly Now, яка повертає поточну дату та час.

Отже, поле - це як властивість, для якої гарантовано повернути те саме значення, якщо поле не було встановлено інше значення.

• Метод властивості може спричинити помітні побічні ефекти; доступ до поля ніколи не відбувається.

Знову ж таки, поле - це властивість, яка гарантовано цього не робить.

• метод властивості може вимагати додаткової пам'яті або повернути посилання на те, що насправді не є частиною стану об'єкта, тому зміна повернутого об'єкта не впливає на вихідний об'єкт; запит на поле завжди повертає посилання на об'єкт, який гарантовано є частиною початкового стану об'єкта. Робота з властивістю, яка повертає копію, може бути дуже заплутаною для розробників, і ця характеристика часто не задокументована.

Це може дивуватись, але не тому, що це властивість робить це. Швидше за все, це те, що ледь хто повертає змінні копії у властивості, так що 0,1% випадків дивно.


0

Методи виклику замість властивостей значно знижують читабельність коду, що викликає. Наприклад, в J #, використання ADO.NET було кошмаром, оскільки Java не підтримує властивості та індекси (які по суті є властивостями з аргументами). Отриманий код був надзвичайно потворним, з порожніми дужками виклики методу всюди.

Підтримка властивостей та індексаторів є однією з основних переваг C # над Java.

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