Je viens de réaliser que la construction de la propriété C # peut également être utilisée avec un modificateur d'accès privé :
private string Password { get; set; }
Bien que cela soit techniquement intéressant, je ne peux pas imaginer quand je l'utiliserais car un domaine privé implique encore moins de cérémonie :
private string _password;
et je ne peux pas imaginer quand j'aurais besoin de pouvoir obtenir en interne mais pas définir ou définir mais pas obtenir un champ privé:
private string Password { get; }
ou
private string Password { set; }
mais il y a peut-être un cas d'utilisation avec des classes imbriquées / héritées ou peut-être où un get / set peut contenir de la logique au lieu de simplement restituer la valeur de la propriété, bien que j'aurais tendance à garder les propriétés strictement simples et à laisser les méthodes explicites faire de la logique, par exemple GetEncodedPassword()
.
Quelqu'un utilise-t-il des propriétés privées en C # pour quelque raison que ce soit ou s'agit-il simplement d'une de ces constructions de code techniquement possibles, mais rarement utilisées dans le code réel?
Addenda
Jolies réponses, en les lisant, j'ai choisi ces utilisations pour les propriétés privées:
- lorsque les champs privés doivent être chargés paresseusement
- lorsque les champs privés nécessitent une logique supplémentaire ou sont des valeurs calculées
- car les champs privés peuvent être difficiles à déboguer
- afin de "se présenter un contrat"
- pour convertir / simplifier en interne une propriété exposée dans le cadre de la sérialisation
- encapsuler des variables globales à utiliser dans votre classe
la source
Réponses:
Je les utilise si j'ai besoin de mettre en cache une valeur et que je veux la charger paresseusement.
la source
return _password ?? (_password = CallExpensiveOperation());
return _password ?? (_password = CallExpensiveOperation());
une seule ligne depuis un moment. Ou en fait Resharper le préfère :).private string Password => _password ?? (_password = CallExpensiveOperation());
private string Password => _password ??= CallExpensiveOperation();
CallExpensiveOperation();
est appelé pendant la construction / l'initialisation de l'objet contenant et non pas lors du premier accès à la propriété.L'utilisation principale de ceci dans mon code est l'initialisation paresseuse, comme d'autres l'ont mentionné.
Une autre raison des propriétés privées sur les champs est que les propriétés privées sont beaucoup plus faciles à déboguer que les champs privés. Je veux souvent savoir des choses comme "ce champ est défini de manière inattendue; qui est le premier appelant qui définit ce champ?" et c'est beaucoup plus facile si vous pouvez simplement mettre un point d'arrêt sur le setter et appuyer sur go. Vous pouvez y mettre la connexion. Vous pouvez y mettre des mesures de performances. Vous pouvez effectuer des vérifications de cohérence qui s'exécutent dans la version de débogage.
Fondamentalement, cela se résume à: le code est beaucoup plus puissant que les données . Toute technique qui me permet d'écrire le code dont j'ai besoin est bonne. Les champs ne vous permettent pas d'écrire du code, contrairement aux propriétés.
la source
Personnellement, j'utilise cela même lorsque je n'ai pas besoin de logique sur le getter ou le setter d'une propriété. L'utilisation d'une propriété, même privée, aide à pérenniser votre code afin que vous puissiez ajouter la logique à un getter plus tard, si nécessaire.
Si je pense qu'une propriété peut éventuellement nécessiter une logique supplémentaire, je l'enveloppe parfois dans une propriété privée au lieu d'utiliser un champ, juste pour ne pas avoir à modifier mon code plus tard.
Dans un cas semi-connexe (bien que différent de votre question), j'utilise très fréquemment les setters privés sur les propriétés publiques:
Cela vous donne un getter public, mais garde le setter privé.
la source
Les valeurs calculées sont une bonne utilisation pour les propriétés privées uniquement. Plusieurs fois, j'ai eu des propriétés privées en lecture seule et je fais juste un calcul sur d'autres champs de mon type. Ce n'est pas digne d'une méthode et n'est pas intéressant pour les autres classes, donc c'est une propriété privée.
la source
L'initialisation paresseuse est un endroit où ils peuvent être nets, par exemple
Ensuite, vous pouvez écrire:
this.MyType
partout plutôt quethis.mytype.Value
et résumer le fait qu'il est instancié paresseusement en un seul endroit.Une chose est dommage, c'est que C # ne prend pas en charge l'étendue du champ de sauvegarde sur la propriété (c'est-à-dire le déclarer dans la définition de propriété) pour le masquer complètement et s'assurer qu'il ne peut être accessible que via la propriété.
la source
field-declaration
le champ d'application à l'intérieuraccessor-declarations
a classé le numéro 1 sur ma liste de souhaits C # depuis longtemps. Si vous pouviez le faire concevoir et implémenter dans une future version (réelle), alors je vous ferai un gâteau.La seule utilisation à laquelle je peux penser
la source
private bool IsPasswordSet() { return !String.IsNullOrEmpty(_password); }
Les propriétés et les champs ne sont pas un à un. Une propriété concerne l'interface d'une classe (qu'il s'agisse de son interface publique ou interne), tandis qu'un champ concerne l'implémentation de la classe. Les propriétés ne doivent pas être considérées comme un moyen d'exposer simplement des champs, elles doivent être considérées comme un moyen d'exposer l'intention et le but de la classe.
Tout comme vous utilisez des propriétés pour présenter un contrat à vos consommateurs sur ce qui constitue votre classe, vous pouvez également vous présenter un contrat pour des raisons très similaires. Alors oui, j'utilise des propriétés privées quand cela a du sens. Parfois, une propriété privée peut masquer des détails d'implémentation tels que le chargement paresseux, le fait qu'une propriété est vraiment un conglomérat de plusieurs champs et aspects, ou qu'une propriété doit être virtuellement instanciée à chaque appel (pensez
DateTime.Now
). Il y a certainement des moments où il est logique d'imposer cela même sur vous-même dans le backend de la classe.la source
Je les utilise en sérialisation, avec des choses comme
DataContractSerializer
ou protobuf-net qui supportent cette utilisation (XmlSerializer
ne le fait pas). Il est utile si vous devez simplifier un objet dans le cadre de la sérialisation:la source
Une chose que je fais tout le temps est de stocker des variables / cache "globales" dans
HttpContext.Current
la source
Je les utilise de temps en temps. Ils peuvent faciliter le débogage lorsque vous pouvez facilement insérer un point d'arrêt dans la propriété ou ajouter une instruction de journalisation, etc.
Peut également être utile si vous devez ultérieurement modifier le type de vos données d'une manière ou si vous devez utiliser la réflexion.
la source
J'utilise des propriétés privées pour réduire le code d'accès aux sous-propriétés souvent utilisées.
Il est utile s'il existe de nombreuses sous-propriétés.
la source
Il est courant de modifier uniquement les membres avec des méthodes get / set, même privées. Maintenant, la logique derrière cela est que vous savez que votre get / set se comporte toujours d'une manière particulière (par exemple, déclencher des événements) qui ne semble pas avoir de sens car ceux-ci ne seront pas inclus dans le schéma de propriété ... mais les vieilles habitudes ont la vie dure.
la source
Il est parfaitement logique lorsqu'il existe une logique associée à la propriété set ou get (pensez à l'initialisation paresseuse) et que la propriété est utilisée à quelques endroits de la classe.
Si c'est juste un terrain de support droit? Rien ne me vient à l'esprit comme une bonne raison.
la source
Je sais que cette question est très ancienne mais les informations ci-dessous ne figuraient dans aucune des réponses actuelles.
Si vous injectez vos dépendances, vous voudrez peut-être avoir un Getter sur une propriété et non un setter car cela dénoterait une propriété en lecture seule. En d'autres termes, la propriété ne peut être définie que dans le constructeur et ne peut être modifiée par aucun autre code de la classe.
Visual Studio Professional fournira également des informations sur une propriété et non sur un champ, ce qui facilitera la visualisation de l'utilisation de votre champ.
la source
Eh bien, comme personne ne l'a mentionné, vous pouvez l'utiliser pour valider des données ou pour verrouiller des variables.
Validation
Verrouillage
Remarque: Lorsque vous verrouillez une référence, vous ne verrouillez pas l'accès aux membres de l'objet référencé.
Référence paresseuse: Lors du chargement paresseux, vous devrez peut-être le faire en mode asynchrone pour lequel il existe de nos jours AsyncLazy . Si vous utilisez des versions antérieures à Visual Studio SDK 2015 ou ne l'utilisez pas, vous pouvez également utiliser AsyncLazy d'AsyncEx .
la source
Certaines utilisations plus exotiques des champs explicites incluent:
ref
ouout
avec la valeur - peut-être parce que c'est unInterlocked
compteurstruct
mise en page explicite (peut-être pour mapper vers un vidage C ++, ouunsafe
code)BinaryFormatter
la gestion automatique des champs (le passage aux accessoires automatiques modifie les noms et rompt ainsi le sérialiseur)la source