J'ai vu le Tuple introduit dans .Net 4 mais je ne suis pas capable d'imaginer où il peut être utilisé. Nous pouvons toujours créer une classe ou une structure personnalisée.
Réponses
Trop de publicités?Avec les tuples, vous pouvez facilement mettre en œuvre un dictionnaire bidimensionnel (ou n-dimensionnel, d'ailleurs). Par exemple, vous pourriez utiliser un tel dictionnaire pour mettre en œuvre un mappage de change de devises :
var forex = new Dictionary<Tuple<string, string>, decimal>();
forex.Add(Tuple.Create("USD", "EUR"), 0.74850m); // 1 USD = 0.74850 EUR
forex.Add(Tuple.Create("USD", "GBP"), 0.64128m);
forex.Add(Tuple.Create("EUR", "USD"), 1.33635m);
forex.Add(Tuple.Create("EUR", "GBP"), 0.85677m);
forex.Add(Tuple.Create("GBP", "USD"), 1.55938m);
forex.Add(Tuple.Create("GBP", "EUR"), 1.16717m);
forex.Add(Tuple.Create("USD", "USD"), 1.00000m);
forex.Add(Tuple.Create("EUR", "EUR"), 1.00000m);
forex.Add(Tuple.Create("GBP", "GBP"), 1.00000m);
decimal result;
result = 35.0m * forex[Tuple.Create("USD", "EUR")]; // USD 35.00 = EUR 26.20
result = 35.0m * forex[Tuple.Create("EUR", "GBP")]; // EUR 35.00 = GBP 29.99
result = 35.0m * forex[Tuple.Create("GBP", "USD")]; // GBP 35.00 = USD 54.58
Voici un petit exemple : disons que vous avez une méthode qui doit rechercher l'identifiant et l'adresse électronique d'un utilisateur, à partir d'un identifiant d'utilisateur. Vous pouvez toujours créer une classe personnalisée qui contient ces données, ou utiliser un paramètre ref / out pour ces données, ou vous pouvez simplement retourner un Tuple et avoir une belle signature de méthode sans avoir à créer un nouveau POCO.
public static void Main(string[] args)
{
int userId = 0;
Tuple<string, string> userData = GetUserData(userId);
}
public static Tuple<string, string> GetUserData(int userId)
{
return new Tuple<string, string>("Hello", "World");
}
J'ai utilisé un tuple pour résoudre Problème 11 du projet Euler :
class Grid
{
public static int[,] Cells = { { 08, 02, 22, // whole grid omitted
public static IEnumerable<Tuple<int, int, int, int>> ToList()
{
// code converts grid to enumeration every possible set of 4 per rules
// code omitted
}
}
Maintenant, je peux résoudre tout le problème avec :
class Program
{
static void Main(string[] args)
{
int product = Grid.ToList().Max(t => t.Item1 * t.Item2 * t.Item3 * t.Item4);
Console.WriteLine("Maximum product is {0}", product);
}
}
I pourrait J'aurais pu utiliser un type personnalisé pour cela, mais cela aurait eu l'air exactement comme Tuple .
La syntaxe des tuple de C# est ridiculement volumineuse, et les tuples sont donc difficiles à déclarer. Et comme il n'y a pas de correspondance de motifs, leur utilisation est également pénible.
Mais parfois, vous souhaitez simplement regrouper des objets de manière ad hoc sans créer de classe pour cela. Par exemple, disons que je veux agréger une liste, mais que je veux deux valeurs au lieu d'une :
// sum and sum of squares at the same time
var x =
Enumerable.Range(1, 100)
.Aggregate((acc, x) => Tuple.Create(acc.Item1 + x, acc.Item2 + x * x));
Au lieu de combiner une collection de valeurs en un seul résultat, développons un résultat unique en une collection de valeurs. La façon la plus simple d'écrire cette fonction est la suivante :
static IEnumerable<T> Unfold<T, State>(State seed, Func<State, Tuple<T, State>> f)
{
Tuple<T, State> res;
while ((res = f(seed)) != null)
{
yield return res.Item1;
seed = res.Item2;
}
}
f
convertit un état en un tuple. Nous retournons la première valeur du tuple et définissons notre nouvel état à la deuxième valeur. Cela nous permet de conserver l'état tout au long du calcul.
Vous l'utilisez comme tel :
// return 0, 2, 3, 6, 8
var evens =
Unfold(0, state => state < 10 ? Tuple.Create(state, state + 2) : null)
.ToList();
// returns 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
var fibs =
Unfold(Tuple.Create(0, 1), state => Tuple.Create(state.Item1, Tuple.Create(state.Item2, state.Item1 + state.Item2)))
.Take(10).ToList();
evens
est assez simple, mais fibs
est un peu plus intelligente. Son site state
est en fait un tuple qui contient respectivement fib(n-2) et fib(n-1).