Dois-je utiliser des propriétés publiques et des champs privés ou publics pour des données?

Dans la plupart du code que j’ai vu (sur SO, thecodeproject.com et j’ai tendance à le faire dans mon propre code), j’ai vu des propriétés publiques créées pour chaque champ privé que contient une classe, même si elles sont les plus nombreuses. type de base de get; set; get; set; comme:

 private int myInt; public int MyInt { get { return myInt; } set { myInt = value } } 

Ma question est la suivante: en quoi cela diffère-t-il de:

 public int MyInt; 

et si nous devions utiliser des propriétés au lieu de champs publics, pourquoi devrions-nous les utiliser dans ce cas spécifique? (Je ne parle pas d’exemples plus complexes où les getters et les setters font quelque chose de spécial ou il n’y a qu’un seul get ou set (lecture / écriture uniquement) plutôt que de simplement retourner / définir une valeur d’un champ privé). Il ne semble pas y avoir d’encapsulation supplémentaire, il suffit de donner une belle icône dans IntelliSense et de le placer dans une section spéciale des diagrammes de classes!

Voir cet article http://blog.codinghorror.com/properties-vs-public-variables/

Plus précisément

  • La reflection fonctionne différemment sur les variables et les propriétés, donc si vous utilisez la reflection, il est plus facile d’utiliser toutes les propriétés.
  • Vous ne pouvez pas vous connecter à une variable.
  • Changer une variable en propriété est un changement radical.

Trois raisons:

  1. Vous ne pouvez pas remplacer les champs des sous-classes comme vous pouvez le faire avec les propriétés.
  2. Vous pourriez éventuellement avoir besoin d’un getter ou d’un setter plus complexe, mais si c’est un champ, le changer casserait l’API.
  3. Convention. C’est comme ça que ça se passe.

Je suis sûr qu’il y a plus de raisons auxquelles je ne pense pas.

Dans .Net 3.x, vous pouvez utiliser des propriétés automatiques telles que:

 public int Age { get; set; } 

au lieu de la vieille école avec la déclaration de vos champs privés comme ceci:

 private int age; public int Age { get { return age; } set { age = value; } } 

Cela le rend aussi simple que de créer un champ, mais sans le problème de la rupture (entre autres).

Lorsque vous créez un nom de champ privé et une propriété publique simple Nom qui obtient et définit la valeur du champ de nom

 public ssortingng Name { get { return name; } } 

et vous utilisez cette propriété partout en dehors de votre classe et un jour vous décidez que la propriété Name de cette classe fera en réalité référence au champ lastName (ou que vous voulez retourner une chaîne “My name:” + name), vous modifiez simplement la code à l’intérieur de la propriété:

 public ssortingng Name { get { return lastName; //return "My name: "+name; } } 

Si vous utilisiez un nom de champ public partout dans le code externe, vous devez changer le nom en nom partout où vous l’avez utilisé.

Eh bien, cela fait une différence. Les données publiques peuvent être modifiées sans que l’instance d’object le sache. En utilisant des getters et des setters, l’object est toujours conscient qu’un changement a été effectué.

Rappelez-vous que l’encapsulation des données n’est que le premier pas vers une conception mieux structurée, ce n’est pas un objective en soi.

Vous devez utiliser des propriétés dans les cas suivants:

  1. Lorsque vous devez sérialiser des données dans la propriété à un certain format.
  2. Lorsque vous devez remplacer des propriétés dans une classe dérivée.
  3. Lorsque vous implémentez les méthodes get et set avec une certaine logique. Par exemple, lorsque vous implémentez le modèle Singleton.
  4. Lorsque vous êtes dérivé de l’interface, la propriété a été déclarée.
  5. Lorsque vous avez des problèmes spécifiques liés à la reflection.

Ça dépend?

J’utilise toujours les getters & setters, car ils ont créé ce raccourci:

public int Foo {get; ensemble; }

Au moment de la compilation, il est traduit. Maintenant, vous ne pouvez pas vous en faire, mais c’est là, et si vous avez besoin de fantaisie, il vous suffit de l’épeler plus tard.

Cependant public, privé, protégé … tout dépend de qui vous voulez pouvoir modifier les données. Nous utilisons beaucoup l’inheritance et c’est une méthode très courante pour nous, de sorte que seuls les enfants peuvent éditer certaines propriétés.

 protected _foo; public Foo { get { return _foo; } } //lack of set intentional. 

Il y a plusieurs raisons à cela.

Principalement:

  • Vous pouvez faire d’autres fonctions lorsque la variable est définie
  • Vous pouvez empêcher le réglage et fournir seulement obtenir
  • Certaines choses ne fonctionnent que sur les propriétés (DataBinding, par exemple)
  • Vous pouvez masquer l’implémentation de la propriété [il s’agit peut-être d’une variable ViewState, dans ASP.NET].

Le point est – et si plus bas de la ligne, vous voulez vous assurer que chaque fois que myInt est référencé, quelque chose de spécial se produit (un fichier journal est écrit, il est changé en 42, etc.)? Vous ne pouvez pas faire cela sans getters et setters. Parfois, il est sage de programmer ce dont vous pourriez avoir besoin, pas ce dont vous avez besoin pour le moment.

En fait, si vous utilisez Silverlight, vous réaliserez que les champs ne peuvent pas contenir de ressources statiques et que vous devrez donc utiliser une propriété (même pour accéder à un const ).

Je me suis rendu compte que lorsque j’ai essayé de fédérer les noms de région que j’utilise dans le guidage composite (PRISM).

Cependant, ce ne sont que des limitations de langage et en dehors des champs static / constants, j’utilise toujours des propriétés.

L’idée est que vous ne devriez pas changer accidentellement / involontairement la valeur d’un champ privé de classe à l’extérieur. Lorsque vous utilisez get et set, cela signifie que vous modifiez intentionnellement et sciemment le champ privé de la classe.

Définir une valeur dans un champ privé ne change que ce champ, mais en les rendant dans la propriété, vous pouvez gérer d’autres arguments par exemple, vous pouvez appeler une méthode après avoir défini une valeur

 chaîne privée _email;
 chaîne publique Email
 {
     obtenir
     {
         retourne ceci.
     }
     ensemble
     {
         this._email = valeur;
         ReplaceList ();  // **
     }
 }




En termes plus simples, la réponse à votre question est celle des modificateurs d’access, à savoir publics et privés.

Si tu utilises:

 public int myInt; public int MyInt { get { return myInt; } set { myInt = value } } 

alors les deux propriétés MyInt et myInt sont disponibles dans le projet à modifier. Cela signifie que si votre classe suppose que A est hérité par la classe, supposez B, alors myInt et MyInt peuvent tous deux être modifiés et aucune vérification ne peut être appliquée. Supposons que vous vouliez que la valeur de myInt puisse être définie dans la classe dérivée si une condition particulière passe.

Cela ne peut être réalisé qu’en rendant le domaine privé et la propriété publique. Ainsi, seule la propriété est disponible et les conditions peuvent être définies en fonction de cela.

Je ne peux pas croire qu’avec 11 réponses, personne n’a dit ceci:

Tous les champs privés ne doivent pas être exposés en tant que propriétés publiques. Vous devriez certainement utiliser des propriétés pour tout ce qui doit être non privé, mais vous devriez garder autant de votre classe privée que possible.