J'ai généralement utilisé le KeyValuePair<TKey,TValue>
type chaque fois que j'ai des données liées à des paires dans le sens où l'une est une clé pour l'autre. Si les données ne sont pas liées, le Tuple<T1,T2>
type a plus de sens et j'irais avec ça.
Maintenant, je viens de lire cet article sur les raisons pour lesquelles il faut généralement éviter KeyValuePair<TKey,TValue>
et préférer Tuple<T1,T2>
. Le principal argument étant l'avantage de performance de Tuple<T1,T2>
.
En dehors des performances, y a-t-il une raison pour laquelle un KVP serait un meilleur choix qu'un Tuple<T1,T2>
?
KeyValuePair
est une clé et une valeur, aTuple<T1,T2>
est juste une paire de valeurs égales . Vous pouvez également demander: "pourquoi devrais-je utiliser unList<Class>
si je peux utiliserDictionary<A,B>
".Réponses:
Eh bien, le type pourrait être considéré comme mal nommé, par exemple. Un KeyValuePair tel que nommé doit représenter une clé et une valeur. Et si vos deux objets ne sont pas vraiment une clé et une valeur, juste deux choses? Si je devais voir une méthode ou une propriété qui avait un type de
KeyValuePair<TKey, TValue>
, je m'attendrais à ce que les valeurs du KVP soient une clé et une valeur. Il s'agit simplement de communiquer l'intention et de la faire comprendre à vous-même à l'avenir, ou éventuellement à d'autres membres de l'équipe. Un tuple n'indique pas ce type d'association.Les tuples facilitent également l'ajout d'une autre valeur, ce qui en fait un 3-tuple (ou un triplet, comme vous voulez l'appeler). Certains langages .NET, comme F #, ont également une syntaxe spéciale autour des tuples.
Pour une perspective de mise en œuvre,
Tuple
beaucoup de chosesKeyValuePair
ne le font pas. Les tuples sont comparables, ils implémentent les interfacesIComparable
etIStructuralEquatable
, ce qui facilite la comparaison de deux tuples.la source
KeyValuePair
est struct etTuple
est une classe.C'est la principale différence qui influence la manière dont les objets sont copiés que ce soit par référence ou par valeurs.
et par conséquent,
Tuple<T1,T2>
lorsqu'il est transmis, il utilise simplement "4 octets" dans le système d'exploitation 32 bits, alors qu'il enKeyValuePair<K,V>
faut plus basé sur "K et V"Quoi qu'il en soit, comparer Tuple et KeyValuePair n'est pas une bonne idée (cela n'a pas de sens pour moi) car les deux servent des objectifs différents.
la source
Malgré la sémantique, les performances peuvent être une considération importante lorsque vous envisagez les deux options. Comme mentionné précédemment, the
KeyValuePair
est un type valeur (struct), tandis que theTuple<>
est un type référence (classe). Par conséquent, leKeyValuePair
est alloué sur la pile et leTuple<>
est alloué sur le tas, et le choix optimal est généralement déterminé par les arguments classiques de l' allocation de mémoire pile ou tas . En bref, l'espace de pile est limité, mais a généralement un accès très rapide. La mémoire du tas est beaucoup plus grande mais est un peu plus lente.KeyValuePair<T1, T2>
peut être le meilleur choix si les deux types de clés et la valeur sont primitives (types de valeur commeint
,bool
,double
, etc.) ou struct de petite taille. Avec les types primitifs sur la pile, l'allocation et la désallocation sont rapides comme l'éclair. Cela peut vraiment affecter les performances, en particulier en tant qu'arguments aux appels de méthode récursifs.D'autre part,
Tuple<T1, T2>
est probablement le meilleur choix si l'unT1
ou l' autreT2
des types de référence (comme les classes). UnKeyValuePair
qui contient des pointeurs vers des types de référence (comme les types de clé ou de valeur) va en quelque sorte à l'encontre de l'objectif puisque les objets devront de toute façon être recherchés sur le tas.Voici un benchmark que j'ai trouvé en ligne: Tuple vs KeyValuePair . Le seul problème avec ce benchmark est qu'ils ont testé
KeyValuePair<string, string>
contreTuple<string, string>
, et lestring
type est un type inhabituel et spécial dans .NET en ce qu'il peut se comporter à la fois comme un type valeur et / ou un type référence en fonction du contexte d'exécution. Je crois que l'KeyValuePair<int, int>
aurait été un vainqueur clair contreTuple<int, int>
. Cependant, même avec les lacunes, les résultats montrent que les différences de performance peuvent être importantes:la source
Vous posez vraiment la mauvaise question, la bonne question consiste à utiliser une classe (Tuple) _ mieux qu'un Struct (KVP), auquel cas la réponse est à quoi voulez-vous les utiliser et la réponse est donnée ici Structs versus classes
la source