web-dev-qa-db-fra.com

Quelle exigence le Tuple a-t-il été conçu pour résoudre?

Je regarde la nouvelle fonctionnalité C # des tuples. Je suis curieux, quel problème le Tuple a-t-il été conçu pour résoudre?

Pourquoi avez-vous utilisé des tuples dans vos applications?

Mise à jour

Merci pour les réponses jusqu'à présent, laissez-moi voir si j'ai les choses bien en tête. Un bon exemple de Tuple a été signalé sous forme de coordonnées. Cela semble-t-il correct?

var coords = Tuple.Create(geoLat,geoLong);

Utilisez ensuite le Tuple comme ceci:

var myLatlng = new google.maps.LatLng("+ coords.Item1 + ", "+ coords.Item2 + ");

Est-ce exact?

94
Chaddeus

Lors de l'écriture de programmes, il est extrêmement courant de vouloir regrouper logiquement un ensemble de valeurs qui n'ont pas suffisamment de points communs pour justifier la création d'une classe.

De nombreux langages de programmation vous permettent de regrouper logiquement un ensemble de valeurs autrement sans rapport sans créer de type d'une seule manière:

void M(int foo, string bar, double blah)

Logiquement, c'est exactement la même chose qu'une méthode M qui prend un argument qui est un 3-Tuple de int, string, double. Mais j'espère que vous ne feriez pas réellement:

class MArguments
{
   public int Foo { get; private set; } 
   ... etc

sauf si MArguments avait une autre signification dans la logique métier.

Le concept de "regrouper un tas de données autrement non liées dans une structure plus légère qu'une classe" est utile à de très nombreux endroits, pas seulement pour les listes de paramètres formels de méthodes. C'est utile lorsqu'une méthode a deux choses à renvoyer, ou lorsque vous souhaitez supprimer un dictionnaire de deux données plutôt qu'une seule, et ainsi de suite.

Des langages comme F # qui prennent en charge les types de Tuple nativement offrent une grande flexibilité à leurs utilisateurs; ils constituent un ensemble extrêmement utile de types de données. L'équipe BCL a décidé de travailler avec l'équipe F # pour standardiser un type de Tuple pour le framework afin que chaque langue puisse en bénéficier.

Cependant, à ce stade, il n'y a pas de langue support pour les tuples en C #. Les tuples sont juste un autre type de données comme toute autre classe de framework; il n'y a rien de spécial en eux. Nous envisageons d'ajouter un meilleur support pour les tuples dans les futures versions hypothétiques de C #. Si quelqu'un a des idées sur le type de fonctionnalités impliquant des tuples que vous aimeriez voir, je serais heureux de les transmettre à l'équipe de conception. Les scénarios réalistes sont plus convaincants que les réflexions théoriques.

117
Eric Lippert

Les tuples fournissent une implémentation immuable d'une collection

Mis à part les utilisations courantes des tuples:

  • regrouper des valeurs communes sans avoir à créer une classe
  • pour renvoyer plusieurs valeurs d'une fonction/méthode
  • etc...

Les objets immuables sont intrinsèquement thread-safe:

Les objets immuables peuvent être utiles dans les applications multithread. Plusieurs threads peuvent agir sur les données représentées par des objets immuables sans que les données soient modifiées par d'autres threads. Les objets immuables sont donc considérés comme plus sûrs pour les threads que les objets mutables.

De "Objet immuable" sur wikipedia

22
Evan Plaice

Il fournit une alternative à ref ou out si vous avez une méthode qui doit retourner plusieurs nouveaux objets dans le cadre de sa réponse.

Il vous permet également d'utiliser un type intégré comme type de retour si tout ce que vous avez à faire est de mélanger deux ou trois types existants, et vous ne voulez pas avoir à ajouter une classe/structure uniquement pour cette combinaison. (Avez-vous déjà souhaité qu'une fonction puisse retourner un type anonyme? C'est une réponse partielle à cette situation.)

12
Toby

Il est souvent utile d'avoir un type "paire", juste utilisé dans des situations rapides (comme retourner deux valeurs à partir d'une méthode). Les tuples sont une partie centrale des langages fonctionnels comme F #, et C # les a ramassés en cours de route.

9
Stephen Cleary

très utile pour renvoyer deux valeurs d'une fonction

5
Keith Nicholas

Personnellement, je trouve que Tuples est une partie itérative du développement lorsque vous êtes dans un cycle d'investigation, ou tout simplement "en train de jouer". Parce qu'un tuple est générique, j'ai tendance à y penser lorsque je travaille avec des paramètres génériques - en particulier lorsque je veux développer un morceau de code générique, et je commence à la fin du code, au lieu de me demander "comment j'aimerais cet appel regarder?".

Très souvent, je me rends compte que la collection que les formes de tuple font partie d'une liste, et regarder List> n'exprime pas vraiment l'intention de la liste, ni comment elle fonctionne. Je "vis" souvent avec, mais je me retrouve à vouloir manipuler la liste et changer une valeur - à ce moment-là, je ne veux pas nécessairement créer un nouveau tuple pour cela, donc j'ai besoin de créer ma propre classe ou structure pour le maintenir, donc je peux ajouter du code de manipulation.

Bien sûr, il existe toujours des méthodes d'extension - mais très souvent, vous ne voulez pas étendre ce code supplémentaire à des implémentations génériques.

Il y a eu des moments où je voulais exprimer des données en tant que Tuple, et je n'avais pas de Tuples disponibles. (VS2008) auquel cas je viens de créer ma propre classe Tuple - et je ne la rend pas sécurisée pour les threads (immuable).

Je suppose donc que je suis d'avis que les Tuples sont des programmes paresseux au détriment de la perte d'un nom de type qui décrit son objectif. L'autre dépense est que vous devez déclarer la signature du Tuple partout où il est utilisé comme paramètre. Après un certain nombre de méthodes qui commencent à sembler gonflées, vous pouvez penser comme moi que cela vaut la peine de créer une classe, car elle nettoie les signatures de méthode.

J'ai tendance à commencer par avoir la classe en tant que membre public de la classe dans laquelle vous travaillez déjà. Mais au moment où elle s'étend au-delà d'une simple collection de valeurs, elle obtient son propre fichier et je la déplace hors de la classe qui la contient.

Donc, rétrospectivement, je crois que j'utilise Tuples quand je ne veux pas partir et écrire un cours, et je veux juste penser à ce que j'écris en ce moment. Ce qui signifie que la signature du tuple peut changer beaucoup dans le texte pendant une demi-heure pendant que je détermine quelles données je vais avoir besoin pour cette méthode, et comment elle retourne quelles que soient les valeurs qu'elle renverra.

Si j'ai la chance de refactoriser le code, alors souvent je remets en question la place d'un tuple.

4
Simon Miller

Ancienne question depuis 2010, et maintenant en 2017, Dotnet change et devient plus intelligent.

C # 7 introduit la prise en charge du langage pour les tuples, qui permet aux noms sémantiques des champs d'un Tuple d'utiliser de nouveaux types de Tuple plus efficaces.

Dans vs 2017 et .Net 4.7 (ou en installant le package nuget System.ValueTuple), vous pouvez créer/utiliser un Tuple de manière très efficace et simple:

     var person = (Id:"123", Name:"john"); //create tuble with two items
     Console.WriteLine($"{person.Id} name:{person.Name}") //access its fields

Renvoyer plus d'une valeur d'une méthode:

    public (double sum, double average) ComputeSumAndAverage(List<double> list)
    {
       var sum= list.Sum();
        var average = sum/list.Count;
        return (sum, average);
    }

    How to use:

        var list=new List<double>{1,2,3};
        var result = ComputeSumAndAverage(list);
        Console.WriteLine($"Sum={result.sum} Average={result.average}");    

Pour plus de détails, lisez: https://docs.Microsoft.com/en-us/dotnet/csharp/tuples

2
M.Hassan

Un tuple est souvent utilisé pour renvoyer plusieurs valeurs à partir de fonctions lorsque vous ne souhaitez pas créer un type spécifique. Si vous êtes familier avec Python, Python l'a depuis longtemps.

1
Randy Minder

Une utilisation courante peut être d'éviter de créer des classes/structures qui ne contiennent que 2 champs, au lieu de cela, vous créez un tuple (ou un KeyValuePair pour l'instant). Utile comme valeur de retour, évitez de passer N paramètres ...

1
user347594

Renvoyer plusieurs valeurs d'une fonction. getCoordinates () n'est pas très utile s'il retourne simplement x ou y ou z, mais créer une classe complète et un objet pour contenir trois ints semble également assez lourd.

1
Dean J

Je trouve l'actualisation de KeyValuePair en C # pour itérer sur les paires de valeurs clés dans un dictionnaire.

0
Jubal

Son vraiment utile tout en renvoyant des valeurs des fonctions. Nous pouvons avoir plusieurs valeurs en arrière, ce qui est assez économique dans certains scénarios.

0
Akshat

Je suis tombé sur cette référence de performance entre les paires Tuples et Key-Value et vous la trouverez probablement intéressante. En résumé, il dit que Tuple a un avantage car c'est une classe, donc il est stocké dans le tas et non dans la pile et lorsqu'il est passé en argument, son pointeur est la seule chose qui va. Mais KeyValuePair est un structs donc il est plus rapide à allouer mais il est plus lent lorsqu'il est utilisé.

http://www.dotnetperls.com/Tuple-keyvaluepair

0
Ognyan Dimitrov