Pourquoi C # autorise-t-il les propriétés dans les interfaces?

47

En C #, le code suivant est valide

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

Ce qui n'a aucun sens pour moi. Cela semble casser l'un des principes d'interface les plus importants: le manque d'état (en d'autres termes, pas de champs). La propriété ne crée-t-elle pas un champ privé implicite? Ne serait-ce pas vraiment mauvais pour les interfaces?

Rétablir Monica
la source
12
L'absence d'état est-elle l'un des principes d'une implémentation d' interface ? Pour moi, une interface est un moyen de définir un contrat. En d'autres termes, si une classe implémente une telle interface, elle dispose de toutes les méthodes et propriétés définies dans le contrat.
Florian Margaine
4
Une propriété est juste une méthode get et une méthode set. Comme les interfaces ne sont qu'une liste de méthodes que vous devez implémenter, il est naturel que les interfaces puissent les avoir.
Doval
1
@FlorianMargaine Certes, le concept de contrat est le principe d'interface le plus important, mais le manque d'état est également important. Cela aide à le garder séparé d'une classe abstraite. IE en Java 8, cela finit par être la seule différence majeure entre les interfaces et les classes abstraites.
Rétablir Monica
2
@Doval: Il est naturel qu'une interface déclare de telles méthodes, mais pas qu'elle les implémente.
Giorgio

Réponses:

65

Je pense que la partie déroutante est que si vous écrivez à l' int Property { get; set; }intérieur d'une classe, c'est une propriété automatique avec un champ de support implicite.

Mais si vous écrivez exactement la même chose dans une interface, alors ce n'est pas une propriété automatique , il déclare simplement que la propriété fait partie de l'interface et que tout type qui implémente l'interface doit contenir cette propriété (en tant que propriété automatique ou non ), mais cela ne crée pas le champ de support.

Une façon de voir la différence est d'écrire int Property { get; }: ceci est valable dans une interface et déclare une propriété qui n'a qu'un getter, mais pas de séparateur. Mais il ne compilera pas dans une classe (sauf si vous utilisez C # 6.0), car la propriété auto doit avoir un setter.

svick
la source
18

Définir la propriété telle que vous l'avez montrée est la même chose que définir des méthodes int GetProperty()et void SetProperty(int i). Les propriétés sont puissantes en C #.

Une propriété ne crée pas implicitement un champ privé en C #. Ceci est l'implémentation par défaut d'une auto-property, par exemple public string MyString { get; set;}, mais une propriété qui définit une logique personnalisée dans la getméthode ne génère pas de champ privé implicite.

Enfin, dans la mesure où les interfaces concernent les API publiques , qu'importe si l'implémentation d'une propriété d'interface s'appuie sur un champ privé - implicite ou non? C'est caché des consommateurs de l'interface peu importe.

NWard
la source
Ahh ... Je ne savais pas que cela ne se produisait que pour les propriétés automatiques, et puisque vous devez le remplacer, cela a du sens. Mais si l'interface devait créer une variable privée interne, les développeurs ne l'auraient pas accès - un problème évident.
Rétablir Monica
9
Si vous définissez une propriété dans une interface C #, l'implémentation de cette propriété est laissée à la classe d'implémentation. Elle peut en faire une propriété automatique ou définir une logique personnalisée comme bon leur semble. Aucun champ n'est ajouté à l' interface .
NWard
10

Les propriétés sont des méthodes! Un champ de sauvegarde sera ajouté à la classe qui implémente l'interface (manuellement ou via une propriété automatique).

Roman Reiner
la source
Parfois, il n'y aura pas de champ de support. Bien qu'il soit rare de définir à la fois un get et un ensemble et de ne pas avoir de champ de support pour cela.
Stephen
+1 Les propriétés sont des méthodes! Oui! J'aime écrire les méthodes Propertymeths, mais les collègues qui révisent le code ne le voient pas de cette façon et nous manquons vraiment l'occasion d'encourager de belles encapsulations expressives dans nos programmes.
radarbob
Ces "méthodes de propriété" devraient être rapides cependant, comme aucune recherche de base de données ou quoi que ce soit. Il existe un contrat implicite selon lequel l'accès aux propriétés est rapide. Les méthodes Get * peuvent être lentes.
Trey Mack