Почему 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), потому что авто-свойство должно иметь установщик.

svick
источник
18

Определение свойства, как вы показали, аналогично определению методов int GetProperty()и void SetProperty(int i). Свойства являются мощным сокращением в C #.

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

Наконец, поскольку интерфейсы связаны с общедоступным API, что бы имело значение, если бы реализация свойства интерфейса основывалась на закрытом поле - неявном или ином? Это скрыто от потребителей интерфейса независимо.

NWard
источник
Ааа ... Я не осознавал, что это происходит только для авто-свойств, и так как вы должны переопределить это, это имеет смысл. Но если бы интерфейс должен был создать внутреннюю частную переменную, у разработчиков не было бы доступа к ней - очевидная проблема.
Восстановить Монику
9
Если вы определяете свойство в интерфейсе C #, реализация этого свойства остается за реализующим классом - они могут сделать его авто-свойством или определить собственную логику по своему усмотрению. Поле не добавлено в интерфейс .
NWard
10

Свойства это методы! В класс будет добавлено вспомогательное поле, которое реализует интерфейс (либо вручную, либо через авто-свойство).

Роман Райнер
источник
Иногда не будет заднего поля. Хотя было бы редко определять как get, так и set и не иметь для этого вспомогательного поля.
Стивен
+1 Свойства - это методы! да! Мне нравится писать Propertymethods, но коллеги по анализу кода не видят этого, и мы действительно упускаем возможности для некоторых выразительных инкапсуляций в наших программах.
радаробоб
Эти "методы свойств" должны быть быстрыми, не похожими на БД или что-либо еще. Подразумевается, что доступ к свойству быстрый, методы Get * могут быть медленными.
Трей Мак