Почему C # допускает свойства в интерфейсах?


47

В C # следующий код действителен

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

Что не имеет никакого смысла для меня. Это, кажется, нарушает один из самых важных принципов интерфейсов: отсутствие состояния (другими словами, нет полей). Разве свойство не создает неявное приватное поле? Разве это не очень плохо для интерфейсов?


12
Является ли отсутствие государственной одного из принципов интерфейса реализации ? Для меня интерфейс - это способ определения контракта, т. Е. Если класс реализует такой интерфейс, то он имеет все методы и свойства, определенные в контракте.
Флориан Маргэйн

4
Свойство - это просто метод get и метод set. Поскольку интерфейсы - это просто список методов, которые вы должны реализовать, естественно, что интерфейсы могут иметь их.
Довал

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, но коллеги по анализу кода не видят этого, и мы действительно упускаем возможности для некоторых выразительных инкапсуляций в наших программах.
радаробоб

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