Чому C # допускає властивості в інтерфейсах?


47

У C # діє такий код

interface I{
    int property{get;set;}
}

Що для мене не має сенсу. Це, здається, порушує один з найважливіших принципів інтерфейсів: відсутність стану (іншими словами, відсутні поля). Чи не властивість створює неявне приватне поле? Хіба це не було б дуже погано для інтерфейсів?


12
Є чи відсутність державної одного з принципів інтерфейсу реалізації ? Для мене інтерфейс - це спосіб визначення контракту, тобто якщо клас реалізує такий інтерфейс, то він має всі методи та властивості, визначені в контракті.
Флоріан Маргайн

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

1
@FlorianMargaine Безумовно, концепція контракту є найважливішим принципом інтерфейсів, але відсутність стану також важлива. Це допомагає тримати його окремо від абстрактного класу. IE в Java 8 це, в кінцевому підсумку, є єдиною головною різницею між інтерфейсами та абстрактними класами.
Відновіть Моніку


2
@Doval: Цілком природно, що інтерфейс оголошує такі методи, але не те, що він їх реалізує.
Джорджіо

Відповіді:


65

Я думаю, що заплутана частина полягає в тому, що якщо ви пишете int Property { get; set; }всередині класу, то це автоматеріал із неявним полем резервного копіювання.

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

Один із способів побачити різницю - записати int Property { get; }: це дійсно в інтерфейсі і оголошує властивість, у якій є лише геттер, але не сетер. Але він не буде компілюватися в класі (якщо ви не використовуєте C # 6.0), оскільки для власності авто має бути встановлений.


18

Визначення властивості, як ви показали, те саме, що визначити методи int GetProperty()та void SetProperty(int i). Властивості є потужними в C #.

Властивість не створює неявно приватне поле в C #. auto-propertyНаприклад public string MyString { get; set;}, це реалізація за замовчуванням , наприклад , властивість, яка визначає власну логіку в getметоді, не створює неявне приватне поле.

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


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

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

10

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


Іноді не буде жодного резервного поля. Хоча рідко можна визначити як get і set, а не мати резервного поля для нього.
Стівен

+1 Властивості - це методи! так! Мені подобається писати Propertymethods, але співробітники з перегляду коду так не бачать, і ми дійсно пропускаємо можливості для гарних виразних інкапсуляцій у наших програмах.
radarbob

Ці "властивості методів" повинні бути швидкими, як і ніяких пошукових запитів у БД або нічого подібного. Є контракт, який передбачає, що доступ до власності швидкий, методи Get * можуть бути повільними.
Трей Мак
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.