On nous dit souvent que nous devons protéger l'encapsulation en créant des méthodes getter et setter (propriétés en C #) pour les champs de classe, au lieu d'exposer les champs au monde extérieur.
Mais il y a de nombreuses fois où un champ est juste là pour contenir une valeur et ne nécessite aucun calcul pour obtenir ou définir. Pour ceux-ci, nous ferions tous ce numéro:
public class Book
{
private string _title;
public string Title
{
get{ return _title; }
set{ _title = value; }
}
}
Eh bien, j'ai une confession, je ne pouvais pas supporter d'écrire tout cela (vraiment, il ne fallait pas l'écrire, il fallait le regarder), alors je suis devenu voyou et j'ai utilisé les champs publics.
Ensuite vient C # 3.0 et je vois qu'ils ont ajouté des propriétés automatiques:
public class Book
{
public string Title {get; set;}
}
ce qui est plus ordonné, et j'en suis reconnaissant, mais vraiment, qu'est-ce qui est si différent que de simplement rendre un domaine public?
public class Book
{
public string Title;
}
la source
prop
extrait de code permet de créer rapidement des propriétés. Tapez simplementprop
puis tab.Réponses:
Dans une question connexe que j'avais il y a quelque temps, il y avait un lien vers une publication sur le blog de Jeff, expliquant certaines différences.
Propriétés et variables publiques
Changer une variable en une propriété est un changement de rupture. Par exemple:
la source
ref
ouout
mot clé), tandis qu'une propriété est une paire d'accesseurs et ne peut pas être transmise par référence. Par exemple,bool success = TryGetMyTitle(out myBook.Title);
quelles utilisationsout
fonctionneront avec un champ et ne fonctionneront pas avec une propriété. Ceci est un exemple clair de la raison pour laquelle le changement de champ en propriété est un changement de rupture!ref
/out
, puis définir la propriété à la valeur que la variable locale a alors. Mais alors la méthode appelée n'accède pas elle-même à la propriété, elle accède à la variable locale que vous y avez créée.public int Foo { get; }
ce qui créera une propriété automatique avec un champ de support en lecture seule.Ignorant les problèmes d'API, la chose que je trouve la plus précieuse à propos de l'utilisation d'une propriété est le débogage.
Le débogueur CLR ne prend pas en charge les points d'arrêt de données (la plupart des débogueurs natifs le font). Par conséquent, il n'est pas possible de définir un point d'arrêt sur la lecture ou l'écriture d'un champ particulier sur une classe. Ceci est très limitant dans certains scénarios de débogage.
Les propriétés étant implémentées comme des méthodes très fines, il est possible de définir des points d'arrêt lors de la lecture et de l'écriture de leurs valeurs. Cela leur donne une grande longueur d'avance sur les champs.
la source
Le passage d'un champ à une propriété rompt le contrat (par exemple, tous les codes de référence doivent être recompilés). Ainsi, lorsque vous avez un point d'interaction avec d'autres classes - n'importe quel membre public (et généralement protégé), vous voulez planifier votre croissance future. Pour ce faire, utilisez toujours les propriétés.
Ce n'est rien pour en faire une propriété automatique aujourd'hui, et 3 mois plus tard, vous réaliserez que vous voulez le rendre chargé paresseux et mettre une vérification nulle dans le getter. Si vous aviez utilisé un champ, c'est un changement de recompilation au mieux et impossible au pire, selon qui et quoi d'autre dépend de vos assemblys.
la source
Tout simplement parce que personne ne l'a mentionné: vous ne pouvez pas définir de champs sur les interfaces. Donc, si vous devez implémenter une interface spécifique qui définit les propriétés, les propriétés automatiques sont parfois une fonctionnalité vraiment intéressante.
la source
Une énorme différence qui est souvent négligée et qui n'est mentionnée dans aucune autre réponse: la priorité . Vous pouvez déclarer des propriétés virtuelles et les remplacer alors que vous ne pouvez pas faire de même pour les champs de membre public.
la source
Tout dépend de la gestion des versions et de la stabilité de l'API. Il n'y a pas de différence, dans la version 1 - mais plus tard, si vous décidez que vous devez en faire une propriété avec un certain type de vérification d'erreur dans la version 2, vous n'avez pas à changer votre API - aucun changement de code, n'importe où, autre que la définition du bien.
la source
Un autre avantage des propriétés implémentées automatiquement par rapport aux champs publics est que vous pouvez rendre les accesseurs définis privés ou protégés, en fournissant à la classe d'objets où elle a été définie un meilleur contrôle que celle des champs publics.
la source
Il n'y a rien de mal à créer un champ
public
. Mais n'oubliez pas que la créationgetter/setter
avec desprivate
champs n'est pas une encapsulation. OMI, si vous ne vous souciez pas des autres fonctionnalités d'unProperty
, vous pourriez aussi bien le fairepublic
.la source
Si vous décidez ultérieurement de vérifier que le titre est unique, en le comparant à une collection ou à une base de données, vous pouvez le faire dans la propriété sans modifier le code qui en dépend.
Si vous n'utilisez qu'un attribut public, vous aurez moins de flexibilité.
La flexibilité supplémentaire sans rompre le contrat est ce qui est le plus important pour moi à propos de l'utilisation des propriétés et, jusqu'à ce que j'aie réellement besoin de la flexibilité, la génération automatique est la plus logique.
la source
Une chose que je trouve très utile ainsi que toutes les raisons de code et de test est que s'il s'agit d'une propriété par rapport à un champ, c'est que l'IDE de Visual Studio vous montre les références d'une propriété mais pas d'un champ.
la source
Mon pov a fait quelques recherches
Cela nous donne vraiment plus de possibilités et d'extensibilité.
la source