Dlaczego C # zezwala na właściwości w interfejsach?


47

W języku C # następujący kod jest poprawny

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

To nie ma dla mnie żadnego sensu. Wydaje się to łamać jedną z najważniejszych zasad interfejsów: brak stanu (innymi słowy brak pól). Czy właściwość nie tworzy niejawnego pola prywatnego? Czy to nie byłoby naprawdę złe dla interfejsów?


12
Czy brak stanu jest jedną z zasad implementacji interfejsu ? Dla mnie interfejs jest sposobem na zdefiniowanie kontraktu, tzn. Jeśli klasa implementuje taki interfejs, wówczas ma wszystkie metody i właściwości zdefiniowane w kontrakcie.
Florian Margaine,

4
Właściwość to tylko metoda get i set set. Ponieważ interfejsy to tylko lista metod, które musisz wdrożyć, naturalne jest, że interfejsy mogą je mieć.
Doval

1
@FlorianMargaine Z pewnością koncepcja umowy jest najważniejszą zasadą interfejsów, ale ważny jest również brak stanu. Pomaga to oddzielić go od klasy abstrakcyjnej. IE w Javie 8 jest jedyną dużą różnicą między interfejsami a klasami abstrakcyjnymi.
Przywróć Monikę

2
Ponieważ to nie jest pole. Zobacz, dlaczego interfejsy C # nie mogą zawierać pól?

2
@Doval: Naturalne jest, że interfejs deklaruje takie metody, ale nie implementuje ich.
Giorgio

Odpowiedzi:


65

Myślę, że mylące jest to, że jeśli piszesz int Property { get; set; }wewnątrz klasy, jest to właściwość automatyczna z niejawnym polem zaplecza.

Ale jeśli napiszesz dokładnie to samo w interfejsie, to nie jest to właściwość automatyczna , po prostu deklaruje, że właściwość jest częścią interfejsu i że każdy typ implementujący interfejs musi zawierać tę właściwość (jako auto-właściwość lub nie ), ale nie tworzy pola podkładu.

Jednym ze sposobów dostrzeżenia różnicy jest napisanie int Property { get; }: jest to poprawne w interfejsie i deklaruje właściwość, która ma tylko moduł pobierający, ale nie ustawiający. Ale nie skompiluje się w klasie (chyba że używasz C # 6.0), ponieważ auto-właściwość musi mieć setter.


18

Definiowanie właściwości tak, jak pokazano, jest takie samo, jak definiowanie metod int GetProperty()i void SetProperty(int i). Właściwości są potężnym skrótem w C #.

Właściwość nie tworzy domyślnie pola prywatnego w języku C #. To jest realizacja niewypłacalności auto-property, na przykład public string MyString { get; set;}- jednak właściwość, która określa niestandardową logikę w getmetodzie nie wygeneruje niejawny pole prywatny.

Wreszcie, ponieważ interfejsy dotyczą publicznego interfejsu API, jakie znaczenie miałoby, gdyby implementacja właściwości interfejsu opierała się na polu prywatnym - domyślnym lub innym? To jest ukryte przed konsumentami interfejsu niezależnie.


Ahh ... Nie zdawałem sobie sprawy, że dzieje się tak tylko w przypadku auto-właściwości, a ponieważ musisz to zmienić, ma to sens. Ale jeśli interfejs miałby tworzyć wewnętrzną zmienną prywatną, implementatorzy nie mieliby do niej dostępu - oczywisty problem.
Przywróć Monikę

9
Jeśli zdefiniujesz właściwość w interfejsie C #, implementacja tej właściwości pozostawia się klasie implementującej - mogą oni uczynić ją właściwością automatyczną lub zdefiniować logikę niestandardową według własnego uznania. Do interfejsu nie dodano pola .
NWard

10

Właściwości to metody! Do klasy, która implementuje interfejs, zostanie dodane pole zaplecza (ręcznie lub poprzez auto-właściwość).


Czasami nie będzie pola wsparcia. Chociaż rzadko byłoby zdefiniować zarówno get, jak i set i nie miałby dla niego pola pomocniczego.
Stephen

+1 Właściwości to metody! tak! Lubię pisać Propertymethods, ale współpracownicy zajmujący się przeglądem kodu nie widzą tego w ten sposób i naprawdę brakuje nam okazji na jakieś miłe ekspresyjne enkapsulacje w naszych programach.
radarbob

Te „metody własności” powinny być szybkie, jak brak wyszukiwania DB lub cokolwiek innego. Istnieje domniemana umowa, że ​​dostęp do nieruchomości jest szybki, metody Get * mogą być wolne.
Trey Mack,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.