Y a-t-il des raisons d’utiliser des propriétés privées en C #?

Je viens de me rendre compte que la construction de la propriété C # peut également être utilisée avec un modificateur d’access privé :

private ssortingng Password { get; set; } 

Bien que ce 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 ssortingng _password; 

et je ne peux pas imaginer quand j’aurais jamais besoin de pouvoir obtenir en interne, mais pas définir ou définir, mais ne pas obtenir un champ privé:

 private ssortingng Password { get; } 

ou

 private ssortingng Password { set; } 

mais peut-être y a-t-il un cas d’utilisation avec des classes nestedes / héritées ou peut-être qu’un get / set contiendrait de la logique au lieu de simplement renvoyer la valeur de la propriété. Par exemple, GetEncodedPassword() .

Est-ce que quelqu’un utilise des propriétés privées en C # pour quelque raison que ce soit ou est-ce juste une de ces constructions techniquement possibles, mais rarement utilisées dans le code actuel?

Addenda

Jolies réponses, en les parcourant, j’ai éliminé ces utilisations pour les propriétés privées:

  • lorsque des champs privés doivent être chargés paresseusement
  • lorsque des champs privés ont besoin d’une logique supplémentaire ou sont des valeurs calculées
  • puisque les champs privés peuvent être difficiles à déboguer
  • afin de “présenter un contrat à vous-même”
  • convertir / simplifier en interne une propriété exposée dans le cadre de la sérialisation
  • envelopper les variables globales à utiliser dans votre classe

Je les utilise si j’ai besoin de mettre en cache une valeur et que je souhaite la charger paresseuse.

 private ssortingng _password; private ssortingng Password { get { if (_password == null) { _password = CallExpensiveOperation(); } return _password; } } 

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 par rapport aux champs est que les propriétés privées sont beaucoup plus faciles à déboguer que les zones privées. Je veux souvent savoir des choses comme “ce champ est défini de manière inattendue; qui est le premier appelant à définir ce champ?” et c’est bien plus simple si vous pouvez simplement placer un point d’arrêt sur le setter et appuyer sur go. Vous pouvez y connecter Vous pouvez y placer des mesures de performance. Vous pouvez mettre des contrôles de cohérence qui s’exécutent dans la version de débogage.

Fondamentalement, cela revient à: le code est beaucoup plus puissant que les données . Toute technique qui me permet d’écrire le code dont j’ai besoin est une bonne. Les champs ne vous permettent pas d’écrire du code en eux, les propriétés font.

Peut-être y a-t-il un cas d’utilisation avec des classes nestedes / héritées ou peut-être qu’un get / set peut contenir une logique au lieu de simplement renvoyer la valeur de la propriété

Je l’utilise personnellement 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 à assurer la pérennité de votre code afin que vous puissiez append la logique à un getter ultérieurement, si nécessaire.

Si je pense qu’une propriété peut éventuellement nécessiter une logique supplémentaire, je l’envelopperai parfois dans une propriété privée au lieu d’utiliser un champ, juste pour ne pas avoir à modifier mon code ultérieurement.


Dans un cas semi-lié (bien que différent de votre question), j’utilise très souvent les particuliers sur les propriétés publiques:

 public ssortingng Password { get; private set; } 

Cela vous donne un public getter, mais garde le setter privé.

L’initialisation différée est un endroit où ils peuvent être soignés, par exemple

 private Lazy mytype = new Lazy(/* expensive factory function */); private MyType MyType { get { return this.mytype.Value; } } // In C#6, you replace the last line with: private MyType MyType => myType.Value; 

Vous pouvez alors écrire: this.MyType partout plutôt que this.mytype.Value et encapsuler le fait qu’il est instancié paresseusement dans un seul endroit.

Ce qui est dommage, c’est que C # ne supporte pas de définir le champ de sauvegarde de la propriété (c’est-à-dire de le déclarer dans la définition de propriété) pour le masquer complètement et s’assurer qu’il ne peut être accédé que via la propriété.

Un bon usage pour les propriétés get get privées sont les valeurs calculées. Plusieurs fois, j’ai eu des propriétés privées en lecture seule et il suffit de faire un calcul sur d’autres champs de mon type. Ce n’est pas digne d’une méthode et pas intéressant pour d’autres classes si la propriété privée est.

Le seul usage auquel je puisse penser

 private bool IsPasswordSet { get { return !Ssortingng.IsNullOrEmpty(_password); } } 

Les propriétés et les champs ne sont pas un à un. Une propriété concerne l’interface d’une classe (qu’elle parle de son interface publique ou interne), alors qu’un champ concerne l’implémentation de la classe. Les propriétés ne doivent pas être considérées comme un moyen de simplement exposer 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. Donc, oui, j’utilise des propriétés privées lorsque cela est logique. Parfois, une propriété privée peut masquer des détails d’implémentation tels que le chargement différé, le fait qu’une propriété est réellement un conglomérat de plusieurs champs et aspects, ou qu’une propriété doit être instanciée virtuellement à chaque appel (pensez à DateTime.Now ). Il y a certainement des moments où il est logique d’imposer cela même sur le backend de la classe.

Je les utilise dans la sérialisation, avec des choses comme DataContractSerializer ou protobuf-net qui prennent en charge cette utilisation ( XmlSerializer non). C’est utile si vous avez besoin de simplifier un object dans le cadre de la sérialisation:

 public SomeComplexType SomeProp { get;set;} [DataMember(Order=1)] private int SomePropProxy { get { return SomeProp.ToInt32(); } set { SomeProp = SomeComplexType.FromInt32(value); } } 

Une chose que je fais tout le temps est de stocker les variables / cache “globales” dans HttpContext.Current

 private static ssortingng SomeValue{ get{ if(HttpContext.Current.Items["MyClass:SomeValue"]==null){ HttpContext.Current.Items["MyClass:SomeValue"]=""; } return HttpContext.Current.Items["MyClass:SomeValue"]; } set{ HttpContext.Current.Items["MyClass:SomeValue"]=value; } } 

Je les utilise de temps en temps. Ils peuvent faciliter le débogage des éléments lorsque vous pouvez facilement insérer un point d’arrêt dans la propriété ou append une instruction de journalisation, etc.

Cela peut également être utile si vous devez ultérieurement modifier le type de vos données ou utiliser la reflection.

J’utilise des propriétés privées pour réduire le code d’access aux sous-propriétés qui sont souvent utilisées.

  private double MonitorResolution { get { return this.Computer.Accesories.Monitor.Settings.Resolution; } } 

C’est utile s’il y a beaucoup de sous propriétés.

Il est courant de ne modifier que les membres avec des méthodes get / set, même privées. Maintenant, la logique est que vous savez que votre get / set se comporte toujours d’une manière particulière (par exemple, déclencher des événements), ce qui ne semble pas avoir de sens puisque ceux-ci ne seront pas inclus dans le schéma de propriétés … mais les vieilles habitudes ont la vie dure.

Cela est parfaitement logique lorsqu’il y a une logique associée à l’ensemble de propriétés ou à get (pensez à l’initialisation paresseuse) et que la propriété est utilisée à quelques endroits de la classe.

Si c’est juste un champ de soutien direct? Rien ne me vient comme une bonne raison.

Eh bien, comme personne mentionné, vous pouvez l’utiliser pour valider des données ou pour verrouiller des variables.

  • Validation

     ssortingng _password; ssortingng Password { get { return _password; } set { // Validation logic. if (value.Length < 8) { throw new Exception("Password too short!"); } _password = value; } } 
  • Verrouillage

     object _lock = new object(); object _lockedReference; object LockedReference { get { lock (_lock) { return _lockedReference; } } set { lock (_lock) { _lockedReference = value; } } } 

    Remarque: Lorsque vous verrouillez une référence, vous ne verrouillez pas l'access aux membres de l'object référencé.

Lazy reference: Lorsque vous chargez paresseux, vous devrez peut-être le faire asynchrone pour lequel il existe aujourd'hui AsyncLazy . Si vous utilisez des versions plus anciennes que Visual Studio SDK 2015 ou si vous ne les utilisez pas, vous pouvez également utiliser AsyncLazy d'AsyncEx .