Getters, setters, les propriétés et les meilleures pratiques. Java et C#
Je vais prendre une classe C#, et je suis en train de trouver la meilleure façon de faire les choses. Je viens d'une Java d'arrière-plan et donc je ne suis familier avec Java meilleures pratiques; je suis un C# débutant!
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 y a de nombreuses façons de le faire.
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; }
Qui dois-je utiliser, et quelles sont les mises en garde ou des subtilités de chaque approche? Lors de la création de classes, je suis en général les meilleures pratiques que je sais de Java (en particulier la lecture Efficace Java). Ainsi, par exemple, je suis en favorisant l'immutabilité (en fournissant des setters seulement quand c'est nécessaire). Je suis juste curieux de voir comment ces pratiques s'inscrivent dans les différentes façons de fournir les setters et getters en C#, pour l'essentiel, comment pourrais-je traduire les meilleures pratiques du monde Java en C#?
MODIFIER
J'ai été poster cela dans un commentaire de Jon Skeet réponse mais cela a longtemps:
À propos d'une non-propriété triviale (c'est à dire, avec un traitement important et de validation peut-être)? Pourrais-je encore exposer via une propriété publique, mais avec la logique encapsulé dans get
et set
? Pourquoi/je ferais ça plus le fait d'avoir un setter et getter méthodes (avec des associés de traitement et de validation de la logique).
Vous devez vous connecter pour publier un commentaire.
Pré-C# 6
J'utilise la dernière de ces, pour une propriété triviale. Notez que j'appellerais cela un public propriété à la fois les getters et les setters sont publiques.
Immutabilité est un peu de douleur avec des propriétés implémentées automatiquement - vous ne pouvez pas écrire une auto-propriété qui n'a qu'un getter; le plus proche, vous pouvez venir est:
ce qui n'est pas vraiment immuable... juste immuable à l'extérieur de votre classe. Si vous souhaitez utiliser un réel propriété en lecture seule à la place:
Vous ne voulez certainement pas à écrire
getName()
etsetName()
. Dans certains cas, il est logique d'écrire des méthodes Get/Set plutôt que d'utiliser les propriétés, en particulier si elles peuvent être coûteux, et vous souhaite souligner que. Cependant, vous voulez suivre les .NET convention de nommage de PascalCase pour les méthodes, et vous ne voudriez pas une propriété triviale de ce type à être mis en œuvre avec des méthodes normales de toute façon - une propriété est beaucoup plus idiomatiques ici.C# 6
Hourra, nous avons enfin bon en lecture seule automatiquement mis en œuvre propriétés:
De même pour les propriétés en lecture seule qui ne besoin de faire un peu de travail, vous pouvez utiliser les états-corsé propriétés:
public int Y { get; } = y;
).Si vous avez besoin d'une variable pour stocker des données:
Souhaitez faire apparaître en lecture seule?
Ou encore mieux...
Voulez faire de la valeur de vérifier avant de l'affecter à la propriété?
En général, le GetXyz() et SetXyz() ne sont utilisés que dans certains cas, et vous avez juste à utiliser votre instinct quand il se sent le droit. En général, je dirais que je m'attends à la plupart des get/set propriétés contiennent pas beaucoup de logique et n'ont que très peu, le cas échéant, des effets secondaires inattendus. Si la lecture de la valeur d'une propriété nécessite l'invocation d'un service ou d'obtenir les commentaires d'un utilisateur dans le but de construire l'objet que je me suis demander, alors je l'enveloppent dans une méthode, et de l'appeler quelque chose comme
BuildXyz()
, plutôt que deGetXyz()
.myList.Add()
, par exemple (tant que l'objet est exposé à des modifications, il est mutable).Min
/Max
valeur. Vous voulez vous assurer queMax > Min
? Avoir unSetRange(Min, Max)
peut avoir du sens mais alors, comment allez-vous lire ces valeurs de retour? Readonly Min/Max propriétés? De lever des exceptions pour la saisie de données incorrectes semble que la meilleure façon de gérer cela.Utiliser les propriétés dans C#, pas de méthodes get/set. Ils sont là pour votre confort et il est idiomatiques.
Que pour vos deux C# exemples, l'un est simplement du sucre syntaxique pour les autres. Utiliser la fonction de propriété si vous avez besoin d'un simple wrapper autour d'une variable d'instance, utiliser la version complète lorsque vous avez besoin d'ajouter de la logique dans la lecture et/ou setter.
En C# faveur propriétés pour exposer les champs privés pour obtenir et/ou de l'ensemble. Le thie forme que vous mentionnez est une autoproperty où le get et set de générer automatiquement cachés pivot de la sauvegarde de domaine pour vous.
J'en faveur de l'auto de propriétés lorsque c'est possible, mais vous ne devriez jamais faire une set/get méthode de la paire en C#.
C'est tout simplement un auto-mise en œuvre de la propriété, et est techniquement le même comme une propriété classique. Un champ de stockage sera créé lors de la compilation.
Toutes les propriétés sont finalement convertis à des fonctions, de sorte que le réel compilé mise en œuvre à la fin est la même que vous êtes habitué à en Java.
Utiliser les propriétés implémentées automatiquement lorsque vous n'avez pas à faire des opérations spécifiques sur le champ de stockage. Utiliser une propriété normale autrement. Utiliser les fonctions get et set lorsque l'opération a des effets secondaires ou est gourmand en ressources, utiliser les propriétés autrement.
D'abord laissez-moi vous expliquer ce que vous avez écrit:
Cette structure est également utilisé aujourd'hui, mais il est le plus approprié si vous voulez faire quelques fonctionnalités supplémentaires, par exemple quand une valeur est définie, vous pouvez à analyser afin de capitaliser et de l'enregistrer dans le privé, membre de alter usage interne.
Avec .net framework 3.0
Vous souhaite plus de chance en C#
Indépendamment de la façon dont vous choisissez en C# le résultat est le même. Vous recevrez un backinng variable distincte de getter et setter. En utilisant les propriétés-vous de suivre les meilleures pratiques et c'est donc une question de la façon dont détaillé que vous souhaitez obtenir.
Personnellement je choisirais auto-propriétés, de la dernière version:
public string Name { get; set; }
, depuis qu'ils prennent le moins de place. Et vous pouvez toujours développer à l'avenir si vous avez besoin d'ajouter quelque chose comme la validation.Chaque fois que possible, je préfère public
string Name { get; set; }
que c'est concis et facile à lire. Cependant, il peut y avoir des moments où celle-ci est nécessaireEn C# le meilleur moyen est par le biais des propriétés plutôt que
getX()
etsetX()
méthodes. Notez également que le C# n'exige pas que les propriétés ont à la fois un get et set - vous pouvez avoir obtenir uniquement des propriétés et définir uniquement les propriétés.Comme mentionné précédemment, l'ensemble de ces approches sur le même résultat. La chose la plus importante est que vous choisissez une convention et rester avec elle. Je préfère utiliser les deux dernières de la propriété des exemples.
comme la plupart des réponses ici, l'utilisation Automatique des propriétés. Intuitive, moins de lignes de code et c'est plus propre. Si vous devez sérialiser votre classe, marque de la classe
[Serializable]
/avec[DataConract]
attribut. Et si vous utilisez[DataContract]
marque le membre avecPrivé ou public setter dépend de votre préférence.
Également noter que automatique propriétés nécessitent à la fois des getters et les setters(public ou privé).
Alternativement, si vous voulez seulement obtenir/définir, créer une sauvegarde de domaine vous-même
Lorsque vous allez avec des propriétés il y a une mise en garde qui n'a pas encore été mentionnés: Avec les propriétés que vous ne peut pas avoir de paramétrage de votre getters ou setters.
Par exemple, imaginez que vous souhaitez récupérer un des éléments de liste et souhaitez également appliquer un filtre en même temps. Avec une méthode, vous pouvez écrire quelque chose comme:
En revanche, avec une propriété que vous êtes obligés de retourner d'abord tous les éléments
puis appliquez le filtre dans l'étape suivante, ou vous devez ajouter des propriétés qui exposent les éléments filtrés en fonction de différents critères, qui gonfle votre API:
Ce qui parfois peut être une nuisance, c'est quand vous avez commencé avec une propriété, par exemple
obj.items
et puis découvert plus tard que la méthode getter ou setter-paramétrage est nécessaire ou serait rendre les choses plus facile pour la classe de l'API de l'utilisateur. Vous aurez besoin soit de réécrire votre API et de modifier tous ces endroits dans votre code que l'accès à cette propriété ou de trouver une solution alternative. En revanche, avec une méthode, par exempleobj.getItems()
, il vous suffit d'étendre votre signature de la méthode d'accepter une option "configuration" de l'objet par exempleobj.getItems(options)
sans avoir à les réécrire tous ces lieux que l'appel de votre méthode.Cela étant dit, (auto-mise en œuvre) propriétés en C# sont encore très raccourcis utiles (pour les diverses raisons évoquées ici) car la plupart du temps, le paramétrage peut ne pas être nécessaire – mais cette mise en garde se tient.