Як я можу отримати доступ до змінної резервного копіювання властивості, яка автоматично реалізована?


79

Раніше ми заявляли такі властивості:

public class MyClass
{
    private int _age;

    public int Age
    {
          get{ return _age;  }
          set{ _age = value; }
    }
}

Тепер ми можемо зробити:

public class MyClass
{
    public int Age {get; set;} 
}

Моє питання полягає в тому, як я можу отримати доступ до приватної змінної, яка автоматично створюється за допомогою цього позначення?

Я волів би отримати доступ до приватної змінної, а не до публічної програми доступу "Age". Чи існує позначення за замовчуванням для доступу до приватної змінної, або це просто неможливо?


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

@ spoon16 Чи можете ви навести приклад додавання логіки до аксесуара і в результаті змінити весь свій код? Я насправді не розумів цієї частини.
Оген

Відповіді:


92

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

Якщо ви хочете отримати доступ до приватного учасника, яким користуються ці властивості, це зазвичай з кількох причин:

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

    public class MyClass
    {
        public int Age {get; private set;} 
    }

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


Правда - вони дійсно зменшують код котела, і я також оголошу, що вони зменшують те, що вам потрібно протестувати. Деякі можуть стверджувати, що вам потрібно протестувати get / set вручну, але не з автоматичними властивостями, оскільки ви можете довіряти фреймворку.
Даніель Оже

3
Зразок коду тут помилковий. Це має бути публічний клас MyClass {public int Age {get; приватний набір;}} Я погоджуюся з цією відповіддю. Ви не можете отримати доступ до приватного поля, і якщо вам це потрібно, то ви не повинні спочатку використовувати автоматичні властивості.
hwiechers

hwiechers, дякую за це - у мене було таке редагування, але при спробі виправити форматування я, мабуть, знову натиснув paste та видалив неправильний блок коду. Дох!
Wilka

Зазвичай використовується в об'єктах POCO
RobS

23

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

Не використовуйте автоматичні властивості, якщо у вас є якась складна логіка у вашому класі. Просто йдіть private int _ageі звичайних геттерів / сетерів, як зазвичай.

Автоматичні властивості IMO більше підходять для швидкої реалізації викинутих об'єктів або тимчасових капсул даних, таких як:

public class TempMessage {
    public int FromID { get; set; }
    public int ToID { get; set; }
    public string Message { get; set; }
}

Де не потрібно багато логіки.


Чому додавання складної логіки до вашого класу впливає на те, чи використовували ви автоматичні властивості в цьому класі?
Ерік Шоновер

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

12

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

[CompilerGenerated]
private int <Age>k_BackingField;

public int Age
{
   [CompilerGenerated]
   get
   {
      return this.<Age>k_BackingField;
   }
   [CompilerGenerated]
   set
   {
      this.<Age>k_BackingField = value;
   }

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


10

За лаштунками відбувається те, що відбувається введення змінної приватного члена з префіксом <> k__AutomaticallyGeneratedPropertyField #

З C # 3.0 пояснено автоматичні властивості

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


7

Ви не повинні, і навряд чи вам це потрібно. Якщо вам потрібен доступ до власності, просто використовуйте загальнодоступну власність (наприклад, this.Age). У приватному полі, що підтримує державне майно, немає нічого особливого, використання його на відміну від власності - це просто забобони.


1
Я завжди дивувався, в чому сенс автоматичних властивостей. Якщо у вас немає особливої ​​логіки у ваших геттерах і сеттерах, навіщо вони взагалі?
Matthew Lock

4
@MatthewLock гнучкість. Завдяки прямому польовому доступу ви замикаєтесь на цьому дизайні, якщо ви одночасно не змінюєте весь код клієнта. Але з властивістю, якщо ви вирішите змінити його з «псевдополя» на обчислювану властивість, або якщо ви вирішите додати твердження та перевірки на сеттері, або що є у вас, ви можете зробити це прозоро. Це ще корисніше, якщо ви пишете код бібліотеки, де ви не можете контролювати весь код клієнта.
Клин

2

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

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