Tuple-uri și deconstrucție în C# (.NET)

Grupează câteva valori fără să declari o clasă: (string Nume, int Varsta), cu deconstrucție în variabile separate.

Sintaxă C#
(int Min, int Max) Interval() => (1, 10);   var (min, max) = Interval();

Ce face Tuple-uri și deconstrucție

Tuple-urile din C# 7 (tipul ValueTuple) se scriu între paranteze: ("Ana", 30). Elementele pot avea nume ((string Nume, int Varsta)); fără nume se accesează cu Item1, Item2. Sunt structuri, deci se copiază la atribuire, iar două tuple-uri sunt egale cu == dacă au aceleași valori.

Deconstrucția desface un tuple în variabile: var (nume, varsta) = persoana;. Merge și pentru schimbarea a două valori fără variabilă temporară: (a, b) = (b, a);. Orice tip cu o metodă Deconstruct (de exemplu un record poziționat sau KeyValuePair) se poate deconstrui la fel.

Tuple-urile sunt bune pentru rezultate locale, cu 2-3 valori. Pentru date care circulă prin toată aplicația, un record cu nume clar e mai ușor de întreținut.

Exemple

Exemplul 1: Metodă care returnează două valori

int[] note = [7, 10, 5, 9];

var (min, max) = Extreme(note);
Console.WriteLine($"Minim {min}, maxim {max}");

var rezultat = Extreme([3, 4]);
Console.WriteLine(rezultat.Max);
Console.WriteLine(rezultat);

static (int Min, int Max) Extreme(int[] valori) => (valori.Min(), valori.Max());

Rezultat

Minim 5, maxim 10
4
(3, 4)

Exemplul 2: Schimbare de valori, egalitate și discard

_ (discard) ignoră o valoare de care nu ai nevoie.

int a = 1, b = 2;
(a, b) = (b, a);
Console.WriteLine($"a={a}, b={b}");

var p1 = (Oras: "Iași", Judet: "IS");
var p2 = ("Iași", "IS");
Console.WriteLine(p1 == p2);

var (_, judet) = p1;
Console.WriteLine(judet);

Rezultat

a=2, b=1
True
IS

Greșeli frecvente

  • Numele elementelor nu fac parte din tip: (int A, int B) și (int X, int Y) sunt compatibile, iar atribuirea poate inversa sensul fără nicio eroare.
  • System.Tuple<T1, T2> (clasa veche, cu Tuple.Create) este alt tip decât ValueTuple: e imutabil, alocat pe heap și nu are nume de elemente. În cod nou folosește sintaxa cu paranteze.

Comenzi înrudite

  • ref, out și in: Transmit un argument prin referință: ref îl poate citi și modifica, out trebuie setat de metodă, in este doar pentru citire.
  • Metode (static, void, return): O metodă grupează cod reutilizabil sub un nume: primește parametri, poate returna o valoare cu return sau nimic (void).
  • Zip: Împerechează elementele a două sau trei secvențe după poziție: primul cu primul, al doilea cu al doilea și așa mai departe.