Je voudrais aller un peu plus loin et l'amener à 3 cas. Bien qu'il y ait des variations sur chacun, ce sont les règles que j'utilise la plupart du temps lors de la programmation en C #.
Dans les cas 2 et 3, accédez toujours à l'accesseur de propriété (pas à la variable de champ). Et dans le cas 1, vous n’êtes même plus obligé de faire ce choix.
1.) Propriété immuable (transmise au constructeur ou créée au moment de la construction). Dans ce cas, j'utilise une variable de champ, avec une propriété en lecture seule. Je choisis ceci par rapport à un poseur privé, puisqu'un poseur privé ne garantit pas l'immutabilité.
public class Abc
{
private readonly int foo;
public Abc(int fooToUse){
foo = fooToUse;
}
public int Foo { get{ return foo; } }
}
2.) variable POCO. Une simple variable pouvant obtenir / définir n'importe quelle portée publique / privée. Dans ce cas, je voudrais simplement utiliser une propriété automatique.
public class Abc
{
public int Foo {get; set;}
}
3.) Propriétés de liaison ViewModel. Pour les classes qui prennent en charge INotifyPropertyChanged, je pense que vous avez besoin d'une variable de champ de sauvegarde privée.
public class Abc : INotifyPropertyChanged
{
private int foo;
public int Foo
{
get { return foo; }
set { foo = value; OnPropertyChanged("foo"); }
}
}
Sheldon Warkentin
la source
public int Foo {get; set;}
au lieu depublic int Foo
?En règle générale, je dirais assigner au champ dans le constructeur et utiliser la propriété partout ailleurs. De cette façon, si quelqu'un ajoute des fonctionnalités à la propriété, vous ne la manquerez nulle part.
Ce n'est certainement pas un facteur de performance. L’optimiseur incorporera un simple get ou set pour vous et le code final MSIL sera probablement identique.
la source
Dépend.
Tout d'abord, vous devriez préférer les propriétés automatiques lorsque cela est possible:
Deuxièmement, la meilleure approche consisterait probablement à utiliser les propriétés. Si vous avez une logique, vous devriez probablement la traverser vous-même, en particulier si cette logique est la synchronisation des threads.
Cependant, vous devez également prendre en compte le fait que cela peut gêner vos performances (un peu), si vous synchronisez incorrectement, vous pouvez vous bloquer, et parfois le chemin correct consiste à contourner la logique de la propriété.
la source
public string MyValue {get; private set;}
.Eh bien, l'approche directe au point serait simplement de l'attribuer à la variable elle-même, puisque vous êtes dans la méthode d'une classe et que vous contrôlez le comportement de la classe, de toute façon.
Mais tout ce qui concerne les propriétés, c'est qu'elles font abstraction de la variable. Alors qu'une propriété aussi simple que dans votre exemple n'a aucune utilité sur une simple variable membre publique, les propriétés font (ou devraient faire) des choses supplémentaires à l'intérieur de leurs getters et setters. Et si vous souhaitez que ces opérations soient effectuées automatiquement lorsque vous modifiez la propriété dans la classe, il est bien sûr préférable de travailler sur la propriété plutôt que sur la variable pour ne pas avoir à modifier chaque affectation de variable lorsque le comportement du paramètre de la propriété change.
Il suffit de raisonner conceptuellement. La propriété est en réalité un handle permettant d'accéder à un état interne de l'objet, qui peut être composé de plusieurs variables membres. Vous devez donc vous demander si vous voulez changer l'état interne sous-jacent seulement (ou seulement une partie de celui-ci) ou la propriété abstraite représentant cet état dans son ensemble, et la plupart du temps, il s'agit bien de ce dernier, car vous voulez généralement que votre objet ait toujours un état cohérent.
la source
S'il existe un risque que l'implémentation get / set de la propriété change parfois ultérieurement (par exemple, si vous souhaitez déclencher un événement lors de l'appel
set
, ou si vous ajouterez un mécanisme d'évaluation paresseux ultérieurement à votreget
fonction), cela peut être une bonne idée que votre code dans la classe utilisera la propriété dans presque tous les cas, sauf dans les cas - très probablement rares - dans lesquels vous ne souhaitez pas explicitement utiliser ces mécanismes d'événement ou d'évaluation paresseux.Quoi qu'il en soit, quoi que vous fassiez, il y a de fortes chances que, lorsque vous modifierez la mise en œuvre de la propriété de cette manière, vous devrez examiner tous les lieux de votre classe accédant à cette propriété pour vérifier si la propriété sera réellement accessible ou si variable privée doit être utilisé.
la source
J'utilise toujours la propriété publique.
Souvent, une logique qui doit toujours être exécutée lorsque la propriété est définie est ajoutée à la
set
méthode d'une propriété, et définir le champ privé à la place du paramètre public contournera toute logique.Vous avez un commentaire à propos de MVVM qui a conduit à cette question, et j'estime que c'est encore plus important lorsque vous travaillez avec MVVM. De nombreux objets émettent une
PropertyChange
notification au créateur, et d'autres objets peuvent s'abonner à cet événement pour exécuter une action lorsque des propriétés spécifiques changent. Si vous définissez la variable privée, ces actions ne seront jamais exécutées à moins que vous ne souleviez également l'PropertyChanged
événement manuellement .la source
Généralement, c'est à vous de décider de ce que vous devez faire avec une propriété et son champ de sauvegarde lorsque vous obtenez / définissez.
Le plus souvent, pour que le code soit cohérent, vous devez utiliser des accesseurs publics partout où ils sont disponibles et appropriés. Cela vous permet de refactoriser avec un minimum de changement de code; si la méthode utilisant ce paramètre doit être supprimée de la classe et placée ailleurs, là où le champ de support n'est plus disponible (comme une classe de base), qui s'en soucie? Vous utilisez quelque chose qui est disponible partout où la classe elle-même doit faire le travail. Le champ de support, dans la plupart des cas, est un détail d'implémentation; personne en dehors de votre classe ne devrait savoir qu'il existe.
La situation principale à laquelle je peux penser quand vous devez utiliser le champ de sauvegarde et NON PAS l'accesseur de propriété est quand l'accesseur a une logique supplémentaire (validation ou mise à jour d'autres informations d'état dans la classe) que vous ne voulez pas exécuter. La population initiale d'un objet est un exemple; vous pouvez avoir une classe qui utilise deux valeurs de propriété pour en calculer une troisième, qui est également stockée dans un champ de sauvegarde (pour des raisons de persistance). Lors de l'initialisation d'une nouvelle copie de cet objet à partir des données de la base de données, les accesseurs de propriété qui recalculent chacun la troisième valeur peuvent se plaindre si l'autre valeur nécessaire n'est pas définie. En utilisant les champs de support pour définir les valeurs initiales de ces deux (ou trois) propriétés, vous contournez la logique de validation / calcul jusqu'à ce que l'instance soit dans un état suffisamment cohérent pour que la logique fonctionne normalement.
la source
Toujours utiliser celui qui a du sens. Oui, je sais que cela semble assez faux au point d’être une non-réponse.
Le point de propriétés est de fournir une interface par laquelle vous pouvez accéder en toute sécurité à un modèle de données. Dans la plupart des situations, vous souhaitez toujours accéder en toute sécurité au modèle de données via cette interface, par exemple:
Mais dans d'autres situations, vous pouvez simplement utiliser une propriété comme vue d'un modèle de données:
S'il est judicieux d'utiliser la forme radians de
SomeAngle
, alors utilisez-la.À la fin, assurez-vous de boire votre propre kool-aid. Votre API faisant face au public doit être suffisamment résiliente pour fonctionner en interne.
la source