Je suis actuellement en cours de C # et j'essaie de trouver la meilleure façon de faire les choses. Je viens d'un milieu Java et je ne connais donc que les meilleures pratiques Java; Je suis novice en C #!
En Java, si j'ai une propriété privée, je le fais;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
En C #, je vois qu'il existe de nombreuses façons de faire cela.
Je peux le faire comme Java:
private string name;
public void setName(string name) {
this.name = name;
}
public string getName() {
return this.name;
}
Ou je peux le faire de cette façon:
private string name;
public string Name {
get { return name; }
set { name = value; }
}
Ou:
public string Name { get; set; }
Lequel devrais-je utiliser et quelles sont les mises en garde ou les subtilités impliquées dans chaque approche? Lors de la création de classes, je suis les meilleures pratiques générales que je connais de Java (en particulier la lecture de Effective Java). Ainsi par exemple, je privilégie l'immuabilité (fournir des setters uniquement lorsque cela est nécessaire). Je suis simplement curieux de voir comment ces pratiques s'intègrent dans les différentes manières de fournir des setters et des getters en C #; essentiellement, comment traduire les meilleures pratiques du monde Java en C #?
ÉDITER
J'étais en train de poster ceci en commentaire de la réponse de Jon Skeet, mais cela est devenu long:
Qu'en est-il d'une propriété non triviale (c'est-à-dire avec un traitement et une validation importants peut-être)? Pourrais-je toujours l'exposer via une propriété publique mais avec la logique encapsulée dans get
et set
? Pourquoi ferais-je / devrais-je faire cela au lieu d'avoir des méthodes setter et getter dédiées (avec la logique de traitement et de validation associée).
la source
public int Y { get; } = y;
).Si vous n'avez besoin que d'une variable pour stocker certaines données:
Vous voulez le faire apparaître en lecture seule?
Ou encore mieux ...
Vous souhaitez vérifier la valeur avant d'attribuer la propriété?
En général, GetXyz () et SetXyz () ne sont utilisés que dans certains cas, et vous n'avez qu'à utiliser votre instinct quand vous vous sentez bien. En général, je dirais que je m'attends à ce que la plupart des propriétés get / set ne contiennent pas beaucoup de logique et aient très peu, voire aucun effet secondaire inattendu. Si la lecture d'une valeur de propriété nécessite d'appeler un service ou d'obtenir l'entrée d'un utilisateur afin de créer l'objet que je demande, alors je l'envelopperais dans une méthode et l'appellerais quelque chose comme
BuildXyz()
, plutôt queGetXyz()
.la source
myList.Add()
, par exemple (tant que l'objet est exposé au changement, il est mutable).Min
/Max
. Vous voulez vous en assurerMax > Min
? Avoir unSetRange(Min, Max)
peut avoir du sens, mais comment allez-vous relire ces valeurs? Propriétés Min / Max en lecture seule? Lancer des exceptions pour une entrée non valide semble être le moyen le plus propre de gérer cela.Utilisez les propriétés en C #, pas les méthodes get / set. Ils sont là pour votre commodité et c'est idiomatique.
Quant à vos deux exemples C #, l'un est simplement du sucre syntaxique pour l'autre. Utilisez la propriété auto si tout ce dont vous avez besoin est un simple wrapper autour d'une variable d'instance, utilisez la version complète lorsque vous devez ajouter une logique dans le getter et / ou le setter.
la source
En C #, privilégiez les propriétés pour exposer les champs privés pour get et / ou set. Le formulaire que vous mentionnez est une propriété automatique où get et set génèrent automatiquement un champ de support de pivot caché pour vous.
Je préfère les propriétés automatiques lorsque cela est possible, mais vous ne devriez jamais faire une paire de méthodes set / get en C #.
la source
Il s'agit simplement d'une propriété implémentée automatiquement et est techniquement la même qu'une propriété normale. Un champ de sauvegarde sera créé lors de la compilation.
Toutes les propriétés sont finalement converties en fonctions, de sorte que l'implémentation compilée réelle à la fin est la même que celle à laquelle vous êtes habitué en Java.
Utilisez les propriétés implémentées automatiquement lorsque vous n'avez pas à effectuer d'opérations spécifiques sur le champ de sauvegarde. Sinon, utilisez une propriété ordinaire. Utilisez les fonctions get et set lorsque l'opération a des effets secondaires ou est coûteuse en calcul, utilisez les propriétés autrement.
la source
Quelle que soit la manière dont vous choisissez en C #, le résultat final est le même. Vous obtiendrez une variable de backinng avec des méthodes getter et setter séparées. En utilisant les propriétés, vous suivez les meilleures pratiques et c'est donc une question de niveau de détail que vous souhaitez obtenir.
Personnellement, je choisirais les propriétés automatiques, la dernière version:,
public string Name { get; set; }
car elles occupent le moins d'espace. Et vous pouvez toujours les développer à l'avenir si vous avez besoin d'ajouter quelque chose comme la validation.la source
Dans la mesure du possible, je préfère le public
string Name { get; set; }
car il est concis et facilement lisible. Cependant, il peut y avoir des moments où celui-ci est nécessairela source
En C #, la méthode préférée consiste à utiliser les propriétés plutôt que
getX()
etsetX()
méthodes. Notez également que C # ne nécessite pas que les propriétés aient à la fois un get et un set - vous pouvez avoir des propriétés get-only et des propriétés set-only.la source
Laissez-moi d'abord essayer d'expliquer ce que vous avez écrit:
Cette structure est également utilisée de nos jours, mais elle est plus appropriée si vous voulez faire des fonctionnalités supplémentaires, par exemple lorsqu'une valeur est définie, vous pouvez l'analyser pour la capitaliser et l'enregistrer dans un membre privé pour une utilisation interne.
Avec .net framework 3.0
Je vous souhaite une meilleure chance en C #
la source
Comme mentionné, toutes ces approches aboutissent au même résultat. Le plus important est que vous choisissiez une convention et que vous vous y teniez. Je préfère utiliser les deux derniers exemples de propriétés.
la source
comme la plupart des réponses ici, utilisez les propriétés automatiques. Intuitif, moins de lignes de code et plus propre. Si vous devez sérialiser votre classe, marquez la classe
[Serializable]
/ avec l'[DataConract]
attribut. Et si vous utilisez[DataContract]
marquer le membre avecLe setter privé ou public dépend de vos préférences.
Notez également que les propriétés automatiques nécessitent à la fois des getters et des setters (publics ou privés).
Sinon, si vous souhaitez uniquement obtenir / définir, créez vous-même un champ de sauvegarde
la source
Lorsque vous utilisez des propriétés, il y a une mise en garde qui n'a pas encore été mentionnée: avec les propriétés, vous ne pouvez pas avoir de paramétrisation de vos getters ou setters.
Par exemple, imaginez que vous souhaitez récupérer des éléments de liste et que vous souhaitez également appliquer un filtre en même temps. Avec une méthode get, vous pouvez écrire quelque chose comme:
En revanche, avec une propriété, vous êtes obligé de renvoyer d'abord tous les éléments
puis appliquez le filtre à l'étape suivante ou vous devez ajouter des propriétés dédiées qui exposent des éléments filtrés par différents critères, ce qui gonfle bientôt votre API:
Ce qui peut parfois être une nuisance, c'est lorsque vous avez commencé avec une propriété, par exemple
obj.items
et que vous avez découvert plus tard qu'une paramétrisation getter ou setter est nécessaire ou faciliterait les choses pour l'utilisateur de l'API de classe. Vous devez maintenant soit réécrire votre API et modifier tous les endroits de votre code qui accèdent à cette propriété, soit trouver une solution alternative. En revanche, avec une méthode get, par exempleobj.getItems()
, vous pouvez simplement étendre la signature de votre méthode pour accepter un objet "configuration" optionnel, par exempleobj.getItems(options)
sans avoir à réécrire tous les endroits qui appellent votre méthode.Cela étant dit, les propriétés (implémentées automatiquement) en C # sont toujours des raccourcis très utiles (pour les différentes raisons mentionnées ici) car la plupart du temps, le paramétrage n'est peut-être pas nécessaire - mais cette mise en garde demeure.
la source