Quand devez-vous placer le type de données Key / Value dans sa propre classe au lieu d'utiliser une structure générique pré-construite, telle que a KeyValuePair
ou a Tuple
?
Par exemple, la plupart des ComboBox que je crée contiennent un DisplayName et une Value. C'est le genre de données que j'essaie de décider quand mettre dans une nouvelle classe et quand utiliser simplement un KeyValuePair.
Je travaille actuellement sur quelque chose qui utilise iCalendar
, et les données de l'utilisateur sélectionné sont finalement combinées en un key1=value1;key2=value2;
type de chaîne. J'ai commencé par mettre les données dans un KeyValuePair<string,string>
, mais maintenant je me demande si cela devrait être sa propre classe à la place.
Dans l'ensemble, je suis intéressé à savoir quelles directives sont utilisées pour décider d'utiliser une structure / classe existante comme un objet KeyValuePair
sur un 2 propriétés, et dans quel genre de situations vous utiliseriez les uns par rapport aux autres.
la source
tuple
type.iCalendar
et je voulais des objets pourBYDAY
etBYSETPOS
. Ils apparaissent dans les zones de liste déroulante, mais les données réelles sont combinées dans la chaîne de règles récurrentes, qui est unkey=value;
type de chaîneRéponses:
J'utiliserais généralement un objet plutôt qu'un KeyValuePair ou un tuple dans la plupart des cas. Tout d'abord, lorsque vous arrivez 6 mois plus tard pour apporter des modifications, il est beaucoup plus facile de comprendre quelle était votre intention plus tôt plutôt que de vous demander ce que
Tuple t
c'est et pourquoi il a ces valeurs amusantes. Deuxièmement, à mesure que les choses grandissent et changent, vous pouvez facilement donner à vos objets de transfert de données un comportement simple selon les besoins. Besoin d'avoir deux formats de nom? Facile, ajoutez simplement les surcharges ToString () appropriées. Vous en avez besoin pour implémenter une interface? Aucun problème. Enfin, il n'y a vraiment pas de surcharge pour créer un objet simple, en particulier avec les propriétés automatiques et l'achèvement du code.Bonus Protip: si vous voulez empêcher ces objets de polluer votre espace de noms, créer des classes privées à l'intérieur des classes est un excellent moyen de garder les choses secrètes et d'éviter les dépendances étranges.
la source
La règle pour définir une nouvelle classe est simple: elle est résumée par "Rasoir d'Occam".
http://c2.com/cgi/wiki?OccamsRazor
N'introduisez pas de nouvelles classes sans une bonne raison. Ou utilisez autant que possible des classes prédéfinies. Ou inventez le moins possible. Cependant, vous êtes à l'aise d'écrire moins de code.
Vous ne pouvez pas utiliser une classe prédéfinie si vous devez attribuer une responsabilité unique à l'objet et que cette responsabilité n'est pas définie dans la classe prédéfinie. Il s'agit souvent d'une méthode unique.
Un
tuple
ouKeyValuePair
est préféré.Jusqu'à ce que.
Vous avez besoin de fonctionnalités qui ne font pas partie de A
tuple
ouKeyValuePair
. Ensuite, vous devez définir votre propre classe.la source
tuple
ouKeyValuePair
»? KeyValuePair a au moins une forme limitée de sémantique, mais les tuples font rarement (cela pourrait être possible, selon le contexte) à mon humble avis. L'introduction d'une nouvelle classe devrait vous donner une sémantique claire comme une évidence.Si vous écrivez votre propre classe, vous avez un endroit clair pour mettre la documentation sur les deux valeurs. D'autant plus que deux cordes ne sont pas une définition très claire. Mais vous pourriez écrire quelque chose comme
la source
MyPair
définit les valeurs de Tuple et à quoi elles servent.Item1
etItem2
! N'est-il pas tout aussi facile de définir toute la classe?public class SideStrings { public string Left { get; set; } public string Right { get; set; } }
S.Lott a écrit
Permettez-moi de dire pourquoi j'ai un sérieux problème avec cela. Puisque
semble être correct .... KeyValue [chaîne, KeyValue [chaîne, KeyValuePair [chaîne, chaîne]]] est également correct? Je ne sais pas ce que dira à S. Lott, mais mon patron pense que c'est correct.
J'ose être en désaccord. Et voici pourquoi: cela réduit la lisibilité du code qui va suivre. La fonction qui remplira une telle structure de données sera beaucoup plus complexe et sujette aux erreurs (err .. exception) (imaginez au moins une logique métier également). Je n'ai pas trop discuté avec mon patron, mais je vais le dire ici: la lisibilité l'emporte sur les économies d'espace minimes (ce qui était son argument). Un objet de classe ne contient donc pas de champs; mais certains restent vides à certains moments mieux?
PS Je suis un Ultra_Noob alors dites-moi si je me trompe.
la source
KeyValuePair<string,string>
c'est bien, en supposant que les choses mises en place sont en effet des clés et des valeurs. Ici, la réutilisation d'une classe existante est une victoire, car vous enregistrez l'écriture de code et gagnez en interopérabilité. OTOH, utiliser quelque chose d'aussi compliqué que laKeyValuePair<string,KeyValuePair<string,string>>
plupart du temps est tout simplement trop compliqué pour être pratique. Parfois, cela peut être juste - lorsque vous n'avez besoin d'aucune fonctionnalité supplémentaire, lorsque le sens est évident et qu'il fonctionne bien avec d'autres classes. YMMV, c'est juste pondérer les avantages et les contras.Lorsque nous parlons de paire clé / valeur , je pense généralement aux tables de hachage , ou aux tableaux associatifs , ou simplement à un objet KeyValuePair . Je les utilise tous et il n'y a pas de différence quand j'utilise lesquels.
Je pense que la chose la plus importante à propos d'une liste de paires clé / valeur est que les clés doivent être uniques (car c'est une clé après tout), et toutes les structures susmentionnées me fournissent vraiment cette fonctionnalité.
En dehors de cela, je veux rechercher par clés ou faire des actions de style liste (tableau) comme push et pop.
Donc, ma réponse est NON et je ne crée pas d'objets explicitement pour les paires clé / valeur, car beaucoup de structures intégrées le font déjà pour moi.
la source
Le chapitre six de Clean Code a une bonne description du moment où utiliser une structure de données par rapport à une classe. En bref, vous utilisez une structure de données lorsque vous prévoyez principalement d'ajouter de nouvelles fonctions pour opérer sur ces données. Vous utilisez une classe lorsque vous prévoyez principalement d'ajouter de nouveaux types de données à exploiter par les fonctions existantes. Votre ComboBox en est un exemple. Vous disposez d'un ensemble de fonctions (l'implémentation ComboBox) fonctionnant sur de nombreux types de données différents (différents types de données pour différents widgets).
la source
Je serais peut-être d'accord avec Wilding ici , mais je suis aussi un peu noob à ce genre de chose aussi.
Je dirais que les types intégrés sont souvent des objets de mécanisme . Par exemple, KeyValuePair fait partie du mécanisme d'un dictionnaire et des tables de hachage, ce qui permet de garantir des clés uniques et des propriétés qui ont des noms significatifs dans le contexte du mécanisme lui-même.
D'autre part, l'utilisation d'objets de données personnalisés offre une meilleure représentation de vos données et offre de nombreux avantages, notamment la lisibilité et l'extensibilité. Il n'y a rien pour arrêter de réutiliser le code existant dans des objets construits sur mesure comme le suggère Sign , mais j'essayerais de masquer la classe encapsulée et d'éviter les fuites d'abstraction , afin que vous puissiez modifier l'implémentation sous-jacente à un stade ultérieur sans affecter le reste de votre code .
Donc la vraie question: représentez-vous des données ou utilisez-vous les données dans un mécanisme? (et je ne conseillerais pas de mélanger ces concepts ensemble).
D'après mon expérience, il n'y a rien de pire que de voir un Tuple [string, string] passé dans une méthode et de n'avoir aucun moyen immédiat de savoir ce que Item1 et Item2 sont censés être. Il est préférable d'utiliser Tuples dans les méthodes ou en tant que membres privés d'une classe uniquement.
la source