private string mWhatever;
private string Whatever
{
get
{
return this.mWhatever;
}
set
{
this.mWhatever = value;
}
}
J'ai vu des gens qui font des propriétés pour chaque membre, privé ou non ... est-ce que cela a un sens? Je pouvais voir que cela avait du sens dans 1% des cas lorsque vous souhaitez contrôler l'accès au membre à l'intérieur de la classe qui le contient, car si vous n'utilisiez pas de propriétés pour chaque membre, cela conduirait à des incohérences et vérifierait si le membre a un accès ou non (puisque vous avez accès aux deux dans le cadre de la classe).
Quelques bonnes réponses ici déjà, mais je pense que la plupart d'entre elles manquent un point de votre question:
Je pense que cela est rarement nécessaire au préalable, pour chaque membre . Commencer avec
Lorsque vous arrivez plus tard à un point où vous avez besoin encapsulation ou d'un point d'arrêt conditionnel pour ce membre spécifique, vous pouvez toujours le remplacer par une propriété du même nom - dans la plupart des cas sans changer le code qui l'utilise
Whatever
. Mais attention, il y a des différences subtiles, voir la réponse de Brian Rasmussen dans cet article SO (lien également donné par Emmad Kareem, +1).la source
L'un des plus grands avantages de cette approche est que vous maîtrisez moment où vos variables changent .
Considérer ce qui suit.
Vous déboguez un grand projet. Une certaine méthode lève une exception. Vous définissez un point d'arrêt et vous révélez qu'une certaine variable membre a une valeur incorrecte. Supposons que votre code repose très largement sur cette variable et que vous trouvez des centaines d'utilisations en écriture ( scénario Spaghetti ). Vous ne pouvez donc pas déterminer lequel de ces utilisations a attribué une mauvaise valeur.
Si le code est multithread, le débogage peut devenir un véritable cauchemar.
Avec la propriété, vous pouvez définir un point d'arrêt dans un setter . Combiné à une condition, il peut être cloué en une seule fois.
VC ++ a des points d'arrêt de données , mais il n'est disponible que pour le code non managé.
la source
Si vous n'utilisez pas de propriété, votre seule autre option consiste à utiliser un champ pour stocker des données variables. Les propriétés et les champs présentent des différences importantes. La plupart de ces différences se trouvent dans les champs par rapport aux propriétés . Je vous propose d'étudier les différences puis de faire votre choix en fonction des besoins de votre application. Cependant, gardez à l'esprit que l'utilisation de champs au lieu de propriétés n'est pas la pratique OO courante en raison de leur nature et de leurs lacunes.
la source
Les propriétés privées peuvent être très utiles pour encapsuler le comportement de choses internes à votre classe. Ce n'est pas parce qu'ils sont privés que vous ne devez pas profiter du sucre syntaxique que vous offrent les propriétés.
L'exemple donné est cependant médiocre. Les getters et setters de propriété de chaudière comme celui-ci sont presque toujours une mauvaise idée. Si vous utilisez C # 3.0 ou une version ultérieure, les propriétés automatiques sont une bien meilleure idée:
C'est plus court, plus propre et beaucoup plus lisible. En fait, c'est à peine plus long que de simplement déclarer la variable de support.
Plus important encore, les propriétés automatiques peuvent être converties en propriétés complètes à tout moment sans changer la sémantique du reste du programme! Ainsi, si vous devez ajouter une validation ou une gestion des erreurs, vous pouvez le faire facilement.
En l'état, j'ai toujours pensé qu'il était dommage que vous ne puissiez pas avoir une propriété en lecture seule, pour appliquer uniquement la possibilité d'écrire sur la valeur dans le constructeur, (je préfère les types immuables ) mais cela a été ajouté en C # 6.0 comme "Auto-Property Initializers", qui vous permet de faire:
ou
de même que
chez le constructeur.
la source
Il n'est pas absolument nécessaire de le faire pour les propriétés privées, mais cela permet de modifier la façon dont la propriété obtient / définit la valeur sous-jacente sans changer la façon dont elle est accessible.
Par exemple, en modifiant la façon dont la valeur sous-jacente est définie:
la source
Ouais
J'utilise personnellement cela comme mécanisme de mise en cache, et nous pourrions l'appeler la mise en cache au niveau de la propriété .
Maintenant, dans d'autres endroits de ma classe, j'utilise une
Users
propriété au lieu d'unusers
champ.Une autre situation possible pourrait être lorsque vous souhaitez implémenter une logique sur un champ, mais de manière centralisée dans une classe. Ainsi, vous pouvez à la fois créer une
GetFoo()
méthode ou uneFoo
propriété pour lefoo
champ.la source
Autre chose à considérer:
Les propriétés réelles sont un détail d'implémentation. L'un des objectifs de la POO est d'essayer de minimiser l'exposition des détails de mise en œuvre lorsque cela est possible.
La raison en est que si vous masquez les propriétés et ne les exposez que par des getters et setters, vous avez bien plus de contrôle. Par exemple, votre getter peut valider son entrée et empêcher la propriété d'être définie sur un état non valide. Si la possibilité de modifier la valeur est critique dans le temps, le passeur peut également se protéger contre cela. Le getter, si obtenir la valeur réelle coûte cher pour une raison quelconque, peut effectuer une initialisation et / ou une mise en cache paresseuse.
Le fait d'avoir des getters et des setters exposés et des propriétés cachées signifie parfois que vous n'avez pas du tout besoin d'une propriété. Votre getter peut calculer la valeur lors de l'invocation, ou déléguer la tâche ailleurs, ou tout ce qui lui permet de répondre à ses spécifications. Ce qui est important dans votre classe, ce sont les informations auxquelles vous pouvez accéder, et non la façon dont ces informations sont représentées en interne.
Bien sûr, s'il n'y a pas de conséquences négatives à ce que quoi que ce soit en dehors de la classe puisse accéder directement à une propriété, vous devez simplement la rendre publique. Cependant, d'après mon expérience, de tels cas sont relativement rares.
la source
Je sais que c'est une vieille question et tout ce que @Yusubov a dit est correct, mais en ce qui concerne son deuxième point sur la logique spécifique dans le setter, et puisque je n'ai vu personne mentionner spécifiquement cela, un exemple parfait serait quand votre classe implémente l'
INotifyPropertyChanged
interface.Ceci est utilisé une tonne dans WCF et Silverlight qui vous permet de savoir quand une propriété spécifique a changé via la logique de son setter comme dans la classe ci-dessous:
la source