Auto-mise en œuvre des getters et les setters et les passations de champs
Je vois beaucoup d'exemple de code pour les classes C# qui fait cela:
public class Point {
public int x { get; set; }
public int y { get; set; }
}
Ou, dans le plus ancien code, le même, avec un explicite privé de la sauvegarde de la valeur et sans les nouvelles propriétés implémentées automatiquement:
public class Point {
private int _x;
private int _y;
public int x {
get { return _x; }
set { _x = value; }
}
public int y {
get { return _y; }
set { _y = value; }
}
}
Ma question est pourquoi. Est-il une différence fonctionnelle entre le faire ci-dessus et juste pour s'ces membres champs publics, comme ci-dessous?
public class Point {
public int x;
public int y;
}
Pour être clair, je comprends la valeur de getters et setters lorsque vous avez besoin de faire de la traduction des données sous-jacentes. Mais dans le cas où vous êtes juste de passage de la valeur au travers, il semble inutilement verbeux.
Vous devez vous connecter pour publier un commentaire.
Je suis plutôt d'accord (qu'il semble inutilement verbeux), bien que cela a été un problème, notre équipe n'a pas encore résolu et donc nos normes de codage de toujours insister sur verbose propriétés pour toutes les classes.
Jeff Atwood traitée il y a quelques années. Le point le plus important, il rétrospectivement à noter, c'est que la modification d'un champ d'une propriété est une modification de rupture dans votre code, tout ce qu'il consomme doivent être recompilés pour travailler avec la nouvelle interface de classe, donc, si quelque chose en dehors de votre contrôle est la consommation de votre classe, vous pourriez avoir des problèmes.
Il est aussi beaucoup plus simple de le changer plus tard:
Il encapsule le réglage et l'accès de ces membres. Si peu de temps à partir de maintenant un développeur pour le code doit changer de logique lorsqu'un membre est accessible ou l'ensemble il peut être fait sans modifier le contrat de la classe.
point.x = 1;
etpoint.x
fonctionnent tout aussi bien.L'idée est que, même si les données sous-jacentes de la structure doit changer, l'interface publique de la classe n'ont pas à être changé.
C# peut traiter les propriétés et les variables différemment à la fois. Par exemple, vous on ne peut pas passer propriétés ref ou des paramètres de sortie. Donc, si vous avez besoin de changer la structure de données pour une raison quelconque et que vous avez été en utilisant les variables et maintenant, vous devez utiliser les propriétés, votre interface devra changer et maintenant le code qui accède à la propriété x ne peut plus compiler comme il l'a fait quand il a été variable x:
L'aide de propriétés de la start permet d'éviter cela, et vous pouvez vous sentir libre de modifier l'implémentation sous-jacente comme beaucoup comme vous devez sans casser le code du client.
Setter et Getter vous permet d'ajouter une couche d'abstraction et pur de la programmation orientée objet, vous devez toujours accès aux objets via l'interface qu'ils fournissent au monde extérieur ...
Considérer ce code, qui va vous sauver asp.net et qu'il ne serait pas possible sans le niveau d'abstraction fournie par les setters et getters:
Depuis l'auto mise en œuvre des getters prend le même nom pour la propriété et le réel de stockage privé variables. Comment pouvez-vous changer dans le futur? Je pense que le point étant dit, c'est que l'utilisation de l'automobile mis en œuvre à la place du champ de sorte que vous pouvez le changer dans le futur si dans le cas où vous avez besoin d'ajouter une logique de getter et setter.
Par exemple:
et par exemple vous utilisez déjà le x beaucoup de fois, et vous ne voulez pas casser votre code.
Comment voulez-vous changer le auto de lecture setter... par exemple pour la définition, vous seulement permettre la définition d'un numéro de téléphone valide format... comment voulez-vous changer le code de sorte que seule la classe est à changer?
Mon idée est d'ajouter une nouvelle variable privée et ajouter le même x getter et setter.
Est-ce que tu veux dire, en la rendant souple?
Également être considéré est l'effet de cette modification à des membres du public quand il s'agit de la liaison et de la sérialisation. Ces deux reposent souvent sur des propriétés publiques pour récupérer et définir des valeurs.
Aussi, vous pouvez mettre des points d'arrêt sur les getters et les setters, mais vous ne pouvez pas sur les champs.
Autant que je sache, le générés CIL interface est différente. Si vous modifiez un membre du public à une propriété, vous de changer l'interface publique et la nécessité de reconstruire tous les fichiers qui utilise cette classe. Ce n'est pas nécessaire si vous modifiez uniquement la mise en œuvre des getters et setters.
Peut-être juste faire des champs de public que vous pourriez vous mène à une plus Anémique Modèle De Domaine.
Salutations
Il est également intéressant de noter que vous ne pouvez pas faire de l'Auto de Propriétés En lecture seule et vous ne pouvez pas initialiser eux en ligne. Ces deux sont des choses que je voudrais voir dans une future version de .NET, mais je crois que vous pouvez le faire ni en .NET 4.0.
La seule fois où j'utilise un champ de stockage avec des propriétés de ces jours, c'est quand ma classe implémente INotifyPropertyChanged et j'ai besoin de feu le OnPropertyChanged cas quand une propriété est modifiée.
Aussi dans ces situations, j'ai défini les champs de sauvegarde directement lorsque les valeurs sont transmises d'un constructeur (pas besoin d'essayer et de feu, la OnPropertyChangedEvent (qui serait NULLE en ce moment de toute façon), n'importe où ailleurs-je utiliser la propriété elle-même.
Vous ne savez jamais si vous ne pourriez pas besoin de la traduction des données plus tard. Vous êtes prêt pour le fait que si vous cacher de vos membres. Les utilisateurs de votre classe l'habitude de préavis, si vous ajoutez la traduction depuis l'interface reste la même.
Le plus grand difrence est que, si jamais vous changez la structure interne, vous pouvez toujours maintenir les getters et setters comme est, en changeant leur logique interne, sans blesser les utilisateurs de votre API.
Si vous devez changer la façon dont vous obtenez x et y dans ce cas, vous pouvez simplement ajouter les propriétés plus tard. C'est ce que je trouve le plus déroutant. Si vous utilisez les variables de membre, vous pouvez facilement changer cela pour une propriété plus tard, et d'utiliser les variables appelées _x et _y si vous avez besoin de stocker la valeur en interne.
Setters et getters sont mauvais en principe (ils sont d'une mauvaise OO odeur--je vais arrêter de dire qu'elles sont un anti-modèle, car ils sont vraiment nécessaires, parfois).
Non, il n'y a techniquement aucune différence et quand j'ai vraiment envie de partager l'accès à un objet ces jours-ci, je l'occasion de le rendre public final au lieu d'ajouter un getter.
La façon dont les setters et getters ont été "Vendu", c'est que vous pourriez avoir besoin de savoir que quelqu'un l'obtention d'une valeur ou de modifier--qui n'a de sens avec les primitives.
Sac de propriétés des objets comme des DAOs, les Dto et objets d'affichage sont exclus de cette règle, parce que ce ne sont pas des objets dans un véritable "OO Design" sens du mot Objet. (Vous ne pensez pas de "Passage de Messages" pour un DAO, C'est tout simplement un tas de paires attribut/valeur).