Astuces DotNet (Sébastien Courtois)

21/04/2010

[Nouveautés .NET 4] Le Tuple

Filed under: .NET, C# 4, Débutant — Étiquettes : , , , , — sebastiencourtois @ 10:05

La classe Tuple est une nouvelle classe de base du Framework .NET 4. Cette classe permet de stocker des données ayant “une relation logique” au sein d’une application.

On peut stocker 1 à 7 valeurs au sein d’un tuple grâce aux classes suivantes :

public class Tuple<T1>

public class Tuple<T1, T2>
public class Tuple<T1, T2, T3>
public class Tuple<T1, T2, T3, T4>
public class Tuple<T1, T2, T3, T4, T5>
public class Tuple<T1, T2, T3, T4, T5, T6>
public class Tuple<T1, T2, T3, T4, T5, T6, T7>

Afin d’utiliser un tuple, il suffit de créer une instance en fournissant les types que l’on souhaite stocker en paramètres générique de la classe. On obtient ainsi une classe typés ce qui permet d’éviter les problèmes de performances liés aux boxing/unboxing.

Tuple<string, int> tsi = new Tuple<string, int>(string.Empty, 0);
Tuple<string, int,bool> tsib = new Tuple<string, int,bool>(string.Empty, 0,true);

Un tuple s’instancie comme une classe normale. On fait appel au constructeur en fournissant les données que l’on souhaite stocker conjointement. Il est intéressant de noter que, gràce à la généricité, on peut imbriquer les tuples et ainsi stocker théoriquement une infinité de données dans un tuple (voir exemple suivant).

Tuple<string, int,bool,int,string,bool,int,Tuple<int,string>> tsib3 =
new Tuple<string, int,bool,int,string,bool,int,Tuple<int,string>> (string.Empty, 0,true,2,string.Empty,true,2,new Tuple<int,string>(2,"Toto"));

L’accès au données se réalise par une propriété ItemX (avec X étant le numéro d’ordre de la donnée) en lecture seule.

public class Tuple<T1, T2> : IStructuralEquatable, IStructuralComparable, IComparable, ITuple
{
    public Tuple(T1 item1, T2 item2)
    public T1 Item1 { get; }
    public T2 Item2 { get; }
}

  • Pourquoi Tuple expose ses propriétés en lecture seule ?

La raison principale est l’immutabilité. On dit qu’une classe est “immutable” si on ne peut modifier ses données qu’au travers de son constructeur. Un des intérêts est que, dans le cas de programmation parralèlle, une classe immutable ne peut être l’objet de verrou ou de race situation car ses données sont figés dans le RAM après la création de la classe. C’est donc uniquement pour des soucis de performances que ces propriétés sont en read only.

Il est toutefois possible de se créer une classe Tuple modifiable en créant la même classe et en rajoutant l’accesseur set sur les propriétés

public class MyTuple<T1, T2>
{
    public MyTuple(T1 t1, T2 t2) { }

    public T1 Item1 { get; set; }
    public T2 Item2 { get; set; }
}
  • Cas d’utilisation des tuples : Les valeurs retours de méthodes

Examinons un exemple pour comprendre une des utlisations des tuples. Je souhaite créer une méthode prenant des données sur une rectangle en paramètres et me fournissant les données sur les coordonnées de deux points de ce rectangle.

En .NET 3.5, je pourrais faire une première méthode avec le mot clé out :

static void CreateRectangleData(string name, int x, int y, int sizex, int sizey,out string finalname,out int p1x,out int p1y,out int p2x,out int p2y)
{
    finalname = name;
    p1x = x;
    p1y = y;
    p2x = x + sizex;
    p2y = y + sizey;
}

L’utilisation de cette méthode peut être fastidieuse car il faut créer l’ensemble des variables du coté de l’appelant. De plus, il serait plus propre de créer une classe intermédiaire pour stocker/structurer ces données.

public class MyRectangle
{
   public string name;
   public int Point1X;
   public int Point1Y;
   public int Point2X;
   public int Point2Y;
}

static MyRectangle CreateRectangleData(string name,int x,int y,int sizex,int sizey)
{
     return new MyRectangle()
     {
       name = name,
       Point1X = x,
       Point1Y = y,
       Point2X = x+sizex,
       Point2Y = y+sizey
    };
}

Meilleure solution (selon moi) pour récupérer ces données. Toutefois, lorsque l’on a trop de classe intermédiaire de ce genre (ne servant souvent qu’à récupérer plusieurs données d’une seul méthode) le code devient vite illisible. C’est là où les tuples peuvent intervenir.

static Tuple<string,int,int,int,int> CreateRectangleData(string name, int x, int y, int sizex, int sizey)
{
   return new Tuple<string, int, int, int, int>(name,x,y,x + sizex,y + sizey);
}

Le code devient donc plus propre car on peut se débarrasser des classes intermédiaires en les remplaçant par des tuples. Il faut toutefois bien être conscient de l’ordre des données afin de ne pas se tromper en les traiter après.

  • Avant j’utilisais KeyValuePair<K,T> et cela marchait très bien. Pourquoi utiliser Tuple<T1,T2> à la place ?

Il faut, tout d’abord, savoir que Tuple est une généralisation de la classe KeyValuePair. On peut décrire KeyValuePair comme étant un Tuple à 2 valeurs alors que Tuple peut prendre N valeurs.

Une différence notable est que Tuple est une classe (type référence) alors que KeyValuePair est une structure (type valeur).

public class Tuple<T1, T2> : /**/
{
    public Tuple(T1 item1, T2 item2)
    public T1 Item1 { get; }
    public T2 Item2 { get; }
}

public struct KeyValuePair<TKey, TValue>
{
    public KeyValuePair(TKey key, TValue value);
    public TKey Key { get; }
    public TValue Value { get; }
}

Définition de la classe Tuple Définition de la structure KeyValue Pair

Le choix entre KeyValuePair<K,T> et Tuple<T1,T2> doit aussi être fait selon la logique de votre code. Il est plus logique de stocker des données d’un dictionnaire selon un système de clé/valeur en utilisant KeyValuePair  et d’utiliser Tuple<T1,T2> pour stocker les données d’une méthode ayant deux valeurs retours.

2 commentaires »

  1. […] This post was mentioned on Twitter by Wilfried Woivré, Sébastien Courtois. Sébastien Courtois said: Petit article sur un nouveautés .NET 4 : La class Tuple => http://tinyurl.com/22l8qfm […]

    Ping par Tweets that mention [Nouveautés .NET 4] Le Tuple « Astuces DotNet (Sébastien Courtois) -- Topsy.com — 22/04/2010 @ 22:49

  2. […] lors d’un post précédent un objet “immutable” (en anglais, immuable en vrai français) : Le Tuple”. Toutefois, nous ne sommes pas rentrés dans les détails de ce type d’objet et nous n’avons […]

    Ping par [.NET] Immutabilité et chaines de caractères en .NET « Astuces DotNet (Sébastien Courtois) — 03/05/2010 @ 15:31


RSS feed for comments on this post. TrackBack URI

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Créez un site Web ou un blog gratuitement sur WordPress.com.

%d blogueurs aiment cette page :