Tuple – typy (Referenční dokumentace jazyka C#)
K dispozici v C# 7,0 a novějších funkce řazené kolekce členů poskytuje stručnou syntaxi pro seskupení více datových elementů ve zjednodušené datové struktuře. Následující příklad ukazuje, jak lze deklarovat proměnnou řazené kolekce členů, inicializovat ji a přistupovat k jejím datovým členům:
(double, int) t1 = (4.5, 3);
Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");
// Output:
// Tuple with elements 4.5 and 3.
(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
// Output:
// Sum of 3 elements is 4.5.
Jak ukazuje předchozí příklad, pro definování typu řazené kolekce členů, zadáte typy všech datových členů a volitelně také názvy polí. Nemůžete definovat metody v typu řazené kolekce členů, ale můžete použít metody poskytované rozhraním .NET, jak ukazuje následující příklad:
(double, int) t = (4.5, 3);
Console.WriteLine(t.ToString());
Console.WriteLine($"Hash code of {t} is {t.GetHashCode()}.");
// Output:
// (4.5, 3)
// Hash code of (4.5, 3) is 718460086.
Počínaje jazykem C# 7,3 typy řazené kolekce členů podporují operátory rovnosti == a != . Další informace najdete v oddílu rovnosti řazené kolekce členů .
Typy řazené kolekce členů jsou typy hodnot; prvky řazené kolekce členů jsou veřejné pole. Který zpřístupňuje řazené kolekce členů proměnlivých hodnotových typů.
Poznámka
funkce řazené kolekce členů vyžaduje System.ValueTuple typ a související obecné typy (například System.ValueTuple<T1,T2> ), které jsou k dispozici v rozhraní .net Core a .NET Framework 4,7 a novější. chcete-li použít řazené kolekce členů v projektu, který se zaměřuje na .NET Framework 4.6.2 nebo dříve, přidejte do projektu balíček NuGet System.ValueTuple .
Můžete definovat řazené kolekce členů s libovolným velkým počtem prvků:
var t =
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26);
Console.WriteLine(t.Item26); // output: 26
Použití případů řazených kolekcí členů
Jedním z nejběžnějších případů použití řazených kolekcí členů je jako návratový typ metody. To znamená, že namísto definování out parametrů metodylze seskupit metodu do návratového typu řazené kolekce členů, jak ukazuje následující příklad:
var xs = new[] { 4, 7, 9 };
var limits = FindMinMax(xs);
Console.WriteLine($"Limits of [{string.Join(" ", xs)}] are {limits.min} and {limits.max}");
// Output:
// Limits of [4 7 9] are 4 and 9
var ys = new[] { -9, 0, 67, 100 };
var (minimum, maximum) = FindMinMax(ys);
Console.WriteLine($"Limits of [{string.Join(" ", ys)}] are {minimum} and {maximum}");
// Output:
// Limits of [-9 0 67 100] are -9 and 100
(int min, int max) FindMinMax(int[] input)
{
if (input is null || input.Length == 0)
{
throw new ArgumentException("Cannot find minimum and maximum of a null or empty array.");
}
var min = int.MaxValue;
var max = int.MinValue;
foreach (var i in input)
{
if (i < min)
{
min = i;
}
if (i > max)
{
max = i;
}
}
return (min, max);
}
Jak ukazuje předchozí příklad, můžete pracovat s vrácenou instancí řazené kolekce členů přímo nebo ji dekonstruovat v samostatných proměnných.
Namísto anonymních typůlze také použít typy řazené kolekce členů; například v dotazech LINQ. Další informace najdete v tématu Volba mezi anonymními a řazenými kolekcemi členů.
Obvykle používáte řazené kolekce členů k seskupení volně souvisejících datových prvků. To je obvykle užitečné v rámci privátních a interních nástrojů. V případě veřejného rozhraní API zvažte definování třídy nebo typu struktury .
Názvy polí řazené kolekce členů
Můžete explicitně zadat názvy polí řazené kolekce členů buď v inicializačním výrazu řazené kolekce členů, nebo v definici typu řazené kolekce členů, jak ukazuje následující příklad:
var t = (Sum: 4.5, Count: 3);
Console.WriteLine($"Sum of {t.Count} elements is {t.Sum}.");
(double Sum, int Count) d = (4.5, 3);
Console.WriteLine($"Sum of {d.Count} elements is {d.Sum}.");
Počínaje jazykem C# 7,1, pokud nezadáte název pole, může být odvozen z názvu odpovídající proměnné v inicializačním výrazu řazené kolekce členů, jak ukazuje následující příklad:
var sum = 4.5;
var count = 3;
var t = (sum, count);
Console.WriteLine($"Sum of {t.count} elements is {t.sum}.");
Označuje se jako Inicializátory řazené kolekce členů. Název proměnné není v následujících případech promítnut do pole řazené kolekce členů:
- Kandidátský název je název členu typu řazené kolekce členů, například,
Item3,ToStringneboRest. - Název kandidáta je duplikátem jiného názvu pole řazené kolekce členů, ať už explicitního, nebo implicitního.
V těchto případech buď explicitně zadáte název pole, nebo přístup k poli s jeho výchozím názvem.
Výchozí názvy polí řazené kolekce členů Item1 jsou Item2 , Item3 a tak dále. Můžete vždy použít výchozí název pole, a to i v případě, že je název pole zadán explicitně nebo odvozený, jak ukazuje následující příklad:
var a = 1;
var t = (a, b: 2, 3);
Console.WriteLine($"The 1st element is {t.Item1} (same as {t.a}).");
Console.WriteLine($"The 2nd element is {t.Item2} (same as {t.b}).");
Console.WriteLine($"The 3rd element is {t.Item3}.");
// Output:
// The 1st element is 1 (same as 1).
// The 2nd element is 2 (same as 2).
// The 3rd element is 3.
Přiřazení řazené kolekce členů a porovnání rovnosti řazené kolekce členů nevezmou názvy polí v účtu.
V době kompilace kompilátor nahrazuje názvy polí, které nejsou výchozí, odpovídajícími výchozími názvy. V důsledku toho nejsou explicitně zadané nebo odvozené názvy polí k dispozici v době běhu.
Přiřazení a dekonstrukce řazené kolekce členů
Jazyk C# podporuje přiřazení mezi typy řazené kolekce členů, které splní obě následující podmínky:
- Oba typy řazené kolekce členů mají stejný počet elementů.
- u každé pozice řazené kolekce členů je typ prvku řazené kolekce členů stejný jako nebo implicitně převoditelné na typ odpovídajícího elementu řazené kolekce členů na levé straně.
Hodnoty prvků řazené kolekce členů jsou přiřazeny za pořadí prvků řazené kolekce členů. Názvy polí řazené kolekce členů jsou ignorovány a nejsou přiřazeny, jak ukazuje následující příklad:
(int, double) t1 = (17, 3.14);
(double First, double Second) t2 = (0.0, 1.0);
t2 = t1;
Console.WriteLine($"{nameof(t2)}: {t2.First} and {t2.Second}");
// Output:
// t2: 17 and 3.14
(double A, double B) t3 = (2.0, 3.0);
t3 = t2;
Console.WriteLine($"{nameof(t3)}: {t3.A} and {t3.B}");
// Output:
// t3: 17 and 3.14
Můžete také použít operátor přiřazení = k dekonstrukci instance řazené kolekce členů v samostatných proměnných. Můžete to udělat jedním z následujících způsobů:
Explicitně deklarovat typ každé proměnné uvnitř závorek:
var t = ("post office", 3.6); (string destination, double distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers.Použijte
varklíčové slovo mimo závorky k deklaraci implicitně typových proměnných a nechejte kompilátor odvodit své typy:var t = ("post office", 3.6); var (destination, distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers.Použít existující proměnné:
var destination = string.Empty; var distance = 0.0; var t = ("post office", 3.6); (destination, distance) = t; Console.WriteLine($"Distance to {destination} is {distance} kilometers."); // Output: // Distance to post office is 3.6 kilometers.
Další informace o dekonstrukci řazených kolekcí členů a dalších typů naleznete v tématu dekonstrukce řazených kolekcí členů a dalších typů.
Rovnost řazené kolekce členů
Počínaje jazykem C# 7,3 typy řazené kolekce členů == podporují != operátory a. Tyto operátory porovnávají členy operandu na levé straně s odpovídajícími členy pravého operandu po pořadí prvků řazené kolekce členů.
(int a, byte b) left = (5, 10);
(long a, int b) right = (5, 10);
Console.WriteLine(left == right); // output: True
Console.WriteLine(left != right); // output: False
var t1 = (A: 5, B: 10);
var t2 = (B: 5, A: 10);
Console.WriteLine(t1 == t2); // output: True
Console.WriteLine(t1 != t2); // output: False
Jak ukazuje předchozí příklad, == != operace a neberou v úvahu názvy polí řazené kolekce členů.
Dvě řazené kolekce členů jsou srovnatelné, pokud jsou splněny obě následující podmínky:
- Obě řazené kolekce členů mají stejný počet elementů. Například
t1 != t2není zkompilován, pokudt1at2má různý počet prvků. - Pro každou pozici řazené kolekce členů jsou odpovídající prvky z operandů řazené kolekce na levé straně a na pravé straně porovnatelné s
==!=operátory a. Například není(1, (2, 3)) == ((1, 2), 3)zkompilován, protože není1porovnatelný s(1, 2).
==Operátory a != porovnávají řazené kolekce členů v podobě krátkodobého okruhu. To znamená, že operace se zastaví, jakmile splní pár nerovných prvků nebo dosáhne konců řazených kolekcí členů. Před jakýmkoli porovnáním však jsou vyhodnocovány všechny prvky řazené kolekce členů, jak ukazuje následující příklad:
Console.WriteLine((Display(1), Display(2)) == (Display(3), Display(4)));
int Display(int s)
{
Console.WriteLine(s);
return s;
}
// Output:
// 1
// 2
// 3
// 4
// False
Řazené kolekce členů jako výstupní parametry
Obvykle refaktorujte metodu, která má out parametry do metody, která vrací řazenou kolekci členů. Existují však případy, ve kterých out parametr může být typu řazené kolekce členů. Následující příklad ukazuje, jak pracovat s řazenými kolekcemi členů jako out parametry:
var limitsLookup = new Dictionary<int, (int Min, int Max)>()
{
[2] = (4, 10),
[4] = (10, 20),
[6] = (0, 23)
};
if (limitsLookup.TryGetValue(4, out (int Min, int Max) limits))
{
Console.WriteLine($"Found limits: min is {limits.Min}, max is {limits.Max}");
}
// Output:
// Found limits: min is 10, max is 20
Řazené kolekce členů vs System.Tuple
Řazené kolekce členů jazyka C#, které jsou zálohovány System.ValueTuple typy, se liší od řazených kolekcí členů, které jsou zastoupeny System.Tuple typy. Hlavní rozdíly jsou následující:
ValueTupletypy jsou typy hodnot.Tupletypy jsou odkazové typy.ValueTupletypy jsou proměnlivé.Tupletypy jsou neměnné.- Datové členy
ValueTupletypů jsou pole. Datové členyTupletypů jsou vlastnosti.
specifikace jazyka C#
Další informace najdete v těchto poznámkách k návrhu funkcí:
- Odvodit názvy řazených kolekcí členů (neboli inicializátorů řazené kolekce členů)
- Podpora pro
==!=typy řazené kolekce členů a