web-dev-qa-db-fra.com

Une future version de .NET prendra-t-elle en charge les tuples en C #?

.Net 3.5 ne prend pas en charge les tuples. Dommage, mais vous ne savez pas si la future version de .net prendra en charge les tuples ou non?

69
Graviton

Je viens de lire cet article du magazine MSDN: Building Tuple

En voici des extraits:

La prochaine version 4.0 de Microsoft .NET Framework introduit un nouveau type appelé System.Tuple. System.Tuple est une collection de taille fixe de données de type hétérogène.

Comme un tableau, un tuple a une taille fixe qui ne peut pas être modifiée une fois qu'il a été créé. Contrairement à un tableau, chaque élément d'un Tuple peut être d'un type différent, et un Tuple est en mesure de garantir un typage fort pour chaque élément.

Il existe déjà un exemple de Tuple flottant autour de Microsoft .NET Framework, dans l'espace de noms System.Collections.Generic: KeyValuePair. Bien que KeyValuePair puisse être considéré comme identique à Tuple, car ce sont deux types qui contiennent deux choses, KeyValuePair se sent différent de Tuple car il évoque une relation entre les deux valeurs qu'il stocke (et pour cause, car il prend en charge la classe Dictionary ).

De plus, les tuples peuvent être de taille arbitraire, tandis que KeyValuePair ne contient que deux choses: une clé et une valeur.


Alors que certaines langues comme F # ont une syntaxe spéciale pour les tuples, vous pouvez utiliser le nouveau type de Tuple commun à partir de n'importe quelle langue. En revisitant le premier exemple, nous pouvons voir que bien qu'utiles, les tuples peuvent être trop verbeux dans les langues sans syntaxe pour un tuple:

class Program {
    static void Main(string[] args) {
        Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
        PrintStringAndInt(t.Item1, t.Item2);
    }
    static void PrintStringAndInt(string s, int i) {
        Console.WriteLine("{0} {1}", s, i);
    }
}

En utilisant le mot-clé var de C # 3.0, nous pouvons supprimer la signature de type sur la variable Tuple, ce qui permet un code un peu plus lisible.

var t = new Tuple<string, int>("Hello", 4);

Nous avons également ajouté quelques méthodes d'usine à une classe Tuple statique qui facilite la création de tuples dans un langage qui prend en charge l'inférence de type, comme C #.

var t = Tuple.Create("Hello", 4);
73
Andreas Grech
#region tuples

    public class Tuple<T>
    {
        public Tuple(T first)
        {
            First = first;
        }

        public T First { get; set; }
    }

    public class Tuple<T, T2> : Tuple<T>
    {
        public Tuple(T first, T2 second)
            : base(first)
        {
            Second = second;
        }

        public T2 Second { get; set; }
    }

    public class Tuple<T, T2, T3> : Tuple<T, T2>
    {
        public Tuple(T first, T2 second, T3 third)
            : base(first, second)
        {
            Third = third;
        }

        public T3 Third { get; set; }
    }

    public class Tuple<T, T2, T3, T4> : Tuple<T, T2, T3>
    {
        public Tuple(T first, T2 second, T3 third, T4 fourth)
            : base(first, second, third)
        {
            Fourth = fourth;
        }

        public T4 Fourth { get; set; }
    }

    #endregion

Et pour rendre les déclarations plus jolies:

public static class Tuple
{
    //Allows Tuple.New(1, "2") instead of new Tuple<int, string>(1, "2")
    public static Tuple<T1, T2> New<T1, T2>(T1 t1, T2 t2)
    {
        return new Tuple<T1, T2>(t1, t2);
    }
    //etc...
}
69
dimarzionist

Il existe une mise en œuvre appropriée (pas rapide) Tuple C # dans - Bibliothèques partagées Lokad (Open-source, bien sûr) qui comprend les fonctionnalités requises suivantes:

  • 2 à 5 implémentations immuables de Tuple
  • DebuggerDisplayAttribute approprié
  • Contrôles de hachage et d'égalité appropriés
  • Des aides pour générer des tuples à partir des paramètres fournis (les génériques sont déduits par le compilateur) et des extensions pour les opérations basées sur la collection.
  • testé en production.
15
Rinat Abdullin

L'implémentation de classes Tuple ou la réutilisation de classes F # dans C # n'est que la moitié de l'histoire - cela vous donne la possibilité de créer des tuples avec une relative facilité, mais pas vraiment le sucre syntaxique qui les rend si agréable à utiliser dans des langages comme F #.

Par exemple, en F #, vous pouvez utiliser la correspondance de modèles pour extraire les deux parties d'un tuple dans une instruction let, par exemple

let (a, b) = someTupleFunc

Malheureusement, faire de même en utilisant les classes F # de C # serait beaucoup moins élégant:

Tuple<int,int> x = someTupleFunc();
int a = x.get_Item1();
int b = x.get_Item2();

Les tuples représentent une méthode puissante pour renvoyer plusieurs valeurs à partir d'un appel de fonction sans avoir besoin de surcharger votre code avec des classes jetables, ou d'avoir recours à des paramètres ref ou out moches. Cependant, à mon avis, sans un peu de sucre syntaxique pour rendre leur création et leur accès plus élégants, ils sont d'une utilité limitée.

14
Chris Ballard

À mon avis, la fonctionnalité des types anonymes n'est pas un tuple, mais une construction très similaire. La sortie de certaines requêtes LINQ sont des collections de types anonymes, qui se comportent comme des tuples.

Voici une déclaration, qui crée un Tuple tapé :-) à la volée:

var p1 = new {a = "A", b = 3};

voir: http://www.developer.com/net/csharp/article.php/3589916

12
ChaosSpeeder

C # 7 prend en charge les tuples de manière native:

var unnamedTuple = ("Peter", 29);
var namedTuple = (Name: "Peter", Age: 29);
(string Name, double Age) typedTuple = ("Peter", 29);
5
Tim Pohlmann

Mon open source .NET bibliothèque Sasa a des tuples depuis des années (ainsi que de nombreuses autres fonctionnalités, comme l'analyse MIME complète). Je l'utilise dans le code de production depuis quelques années maintenant.

3
naasking

C # prend en charge les tuples simples via des génériques assez facilement (comme dans une réponse précédente), et avec "taper mumble" (l'une des nombreuses améliorations possibles du langage C #) pour améliorer l'inférence de type, ils pourraient être très, très puissants.

Pour ce que ça vaut, F # prend en charge les tuples nativement, et après avoir joué avec, je ne suis pas sûr que les tuples (anonymes) ajoutent beaucoup ... ce que vous gagnez en brièveté vous perdez très rapidement dans le code clarté.

Pour le code dans une seule méthode, il existe des types anonymes; pour le code sortant d'une méthode, je pense que je m'en tiendrai aux types nommés simples. Bien sûr, si un futur C # rend plus facile de les rendre immuables (tout en étant faciles à travailler), je serai heureux.

3
Marc Gravell

Voici mon ensemble de tuples, ils sont générés automatiquement par un script Python, donc je suis peut-être allé un peu trop loin:

Lien vers le dépôt Subversion

Vous aurez besoin d'un nom d'utilisateur/mot de passe, ils sont tous les deux invités

Ils sont basés sur l'héritage, mais Tuple<Int32,String> ne sera pas comparable à Tuple<Int32,String,Boolean> même s'ils ont les mêmes valeurs pour les deux premiers membres.

Ils implémentent également GetHashCode et ToString et ainsi de suite, ainsi que de nombreuses méthodes d'assistance plus petites.

Exemple d'utilisation:

Tuple<Int32, String> t1 = new Tuple<Int32, String>(10, "a");
Tuple<Int32, String, Boolean> t2 = new Tuple<Int32, String, Boolean>(10, "a", true);
if (t1.Equals(t2))
    Console.Out.WriteLine(t1 + " == " + t2);
else
    Console.Out.WriteLine(t1 + " != " + t2);

Sortira:

10, a != 10, a, True

Si je me souviens bien de mes cours d'informatique, les tuples sont juste des données.

Si vous voulez des données groupées - créez des classes qui contiennent des propriétés. Si vous avez besoin de quelque chose comme KeyValuePair alors ça y est.

1
Tigraine

Pour les rendre utiles dans une table de hachage ou un dictionnaire, vous souhaiterez probablement fournir des surcharges pour GetHashCode et Equals.

0
Bob

Je serais surpris - C # est un langage fortement typé, tandis que les tuples sont adaptés aux langages typés de manière plus dynamique. C # a dérivé plus dynamique au fil du temps, mais c'est du sucre syntaxique, pas un vrai changement dans les types de données sous-jacents.

Si vous voulez deux valeurs dans une instance, un KeyValuePair <> est un substitut décent, bien que maladroit. Vous pouvez également créer une structure ou une classe qui fera la même chose et qui est extensible.

0
Merus