web-dev-qa-db-fra.com

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

Dans la majeure partie du code que j'ai vu (sur SO, thecodeproject.com et moi-même avons tendance à le faire dans mon propre code), j'ai vu des propriétés publiques être créées pour chaque champ privé qu'une classe contient, même s'ils sont les plus type de base de get; set; comme:

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

Ma question est la suivante: en quoi est-ce différent?

public int MyInt;

et si nous devrions utiliser des propriétés plutôt que des champs publics, pourquoi devrions-nous les utiliser dans ce cas particulier? (Je ne parle pas d'exemples plus complexes où les accesseurs effectuent quelque chose de spécial ou il n'y a qu'un seul get ou set (lecture/écriture uniquement) plutôt que de simplement renvoyer/définir une valeur d'un champ privé). Il ne semble pas ajouter d’encapsulation supplémentaire, il suffit de donner une icône Nice dans IntelliSense et d’être placé dans une section spéciale des diagrammes de classes!

55
Callum Rogers

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

Plus précisément 

  • La réflexion fonctionne différemment entre les propriétés et les variables. Par conséquent, si vous utilisez la réflexion, il est plus facile d’utiliser toutes les propriétés.
  • Vous ne pouvez pas rechercher des données avec une variable.
  • Changer une variable en une propriété est un changement radical. 
33
Johnno Nolan

Trois raisons:

  1. Vous ne pouvez pas remplacer les champs dans les sous-classes comme vous pouvez les propriétés.
  2. Vous aurez peut-être besoin d'un getter ou d'un setter plus complexe, mais si c'est un champ, le changer entraînerait la rupture de l'API. 
  3. Convention. C'est comme ça que ça se passe.

Je suis sûr qu'il y a d'autres raisons pour lesquelles je ne pense tout simplement pas.

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

public int Age { get; set; }

au lieu de la vieille école avec déclarer vos champs privés vous-même 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 la question du changement de rupture (entre autres).

21
Max Schmeling

Lorsque vous créez un champ privé name et une propriété publique simple Name qui obtient et définit réellement la valeur du champ name

public string 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 souhaitez renvoyer une chaîne "Mon nom:" + nom), vous changez simplement le code dans la propriété:

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

Si vous utilisiez le champ publicnompartout dans le code extérieur, vous devrez alors modifiernomennom_fampartout où vous l'avez utilisé.

8
agnieszka

Cela fait une différence. Les données publiques peuvent être modifiées sans que l'instance d'objet le sache. À l'aide de getters et de setters, l'objet est toujours conscient du fait qu'une modification a été apportée.

N'oubliez pas que l'encapsulation des données n'est que le premier pas vers une conception mieux structurée, ce n'est pas un objectif en soi.

5
PatrikAkerstrand

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

  1. Lorsque vous avez besoin de sérialiser les données de la propriété dans un format donné.
  2. Lorsque vous devez remplacer les propriétés dans la 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 un modèle Singleton.
  4. Lorsque vous êtes dérivé de l'interface, où la propriété a été déclarée.
  5. Lorsque vous avez des problèmes spécifiques liés à la réflexion.
4
Pavel Podlipensky

Ça dépend?

J'utilise toujours des accesseurs et des 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 en avoir envie, mais c'est là, et si vous avez besoin de fantaisie, vous devez simplement l'épeler plus tard.

Quoiqu'il en soit public, privé, protégé ... tout dépend de qui vous voulez pouvoir modifier les données. Nous utilisons beaucoup l'héritage et c'est une méthode très courante pour nous, afin que seuls les enfants puissent éditer certaines propriétés.

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

En termes plus simples, la réponse à votre question est celle des modificateurs d’accès, c’est-à-dire publics et privés.

Si tu utilises:

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

alors la propriété MyInt et la variable myInt sont toutes deux disponibles dans le projet à modifier . Cela signifie que si votre classe suppose que A hérite de la classe suppose B, alors myInt et MyInt sont disponibles pour modification et aucune vérification ne peut être effectuée. apply . Supposons que vous souhaitiez que la valeur myInt puisse être définie dans la classe derive si une condition particulière réussit.

Cela ne peut être réalisé qu'en rendant le champ privé et que la propriété soit publique . Ainsi, seule la propriété est disponible et les conditions peuvent être définies en conséquence.

0
KamalDeep

Il y a plusieurs raisons pour lesquelles.

Principalement:

  • Vous pouvez effectuer d'autres fonctions lorsque la variable est définie
  • Vous pouvez empêcher le réglage et ne fournir que
  • 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).
0
Noon Silk

Le problème est le suivant: que se passe-t-il si, plus tard dans la ligne, vous voulez vous assurer que chaque fois que myInt est référencé, il se produit quelque chose de spécial (un fichier journal est écrit dans, il est changé en 42, etc.)? Vous ne pouvez pas faire cela sans geters et setters. Parfois, il est sage de programmer pour ce dont vous pourriez avoir besoin, pas pour ce dont vous avez besoin maintenant.

0
Dominic Rodger

En fait, si vous utilisez Silverlight, vous vous rendrez compte que les champs ne peuvent pas être définis comme des ressources statiques et vous devrez donc utiliser une propriété (même pour accéder à une const).

Je me suis rendu compte que lorsque j'ai essayé de fédérer les noms de région que j'utilise dans PRISM (Composite Guidance).

Cependant, il ne s'agit que d'une limitation de la langue et à part des champs static/const, j'utilise toujours des propriétés.

0
R4cOON

L'idée est que vous ne devez pas modifier accidentellement/involontairement la valeur d'un champ privé de classe en dehors de . Lorsque vous utilisez get et set, cela signifie que vous modifiez le champ privé de classe intentionnellement et en connaissance de cause.

0
rayimag

La définition d'une valeur dans un champ privé modifie uniquement ce champ, mais en les définissant comme une 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
 {
 return this._email; 
 } 
 ensemble
 {
 this._email = valeur; 
 ReplaceList (); //**
 } 
} 




0
Myra