Typy řazené kolekce členů (referenční dokumentace jazyka C#)

Funkce řazených kolekcí členů je k dispozici v jazyce C# 7.0 a novější, poskytuje stručnou syntaxi pro seskupení více datových prvků ve zjednodušené datové struktuře. Následující příklad ukazuje, jak můžete 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, definovat typ kolekce členů, zadáte typy všech jejích datových členů a volitelně názvy polí. Metody typu řazené kolekce členů nelze definovat, 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 podporují typy členů operátory== rovnosti a !=. Další informace najdete v části Rovnost řazené kolekce členů .

Typy řazené kolekce členů jsou typy hodnot; prvky řazené kolekce členů jsou veřejná pole. Díky tomu se řazené typy hodnot řazených kolekcí členů ztlumí .

Poznámka

Funkce řazených kolekcí členů vyžaduje System.ValueTuple typy 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ších verzích. Pokud chcete použít řazené kolekce členů v projektu, který cílí na rozhraní .NET Framework 4.6.2 nebo starší, přidejte do projektu balíček System.ValueTuple NuGet.

Kolekce členů můžete definovat 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

Případy použití řazených kolekcí členů

Jedním z nejběžnějších případů použití řazených kolekcí členů je návratový typ metody. To znamená, že místo definování out parametrů metody můžete seskupit metodu výsledkem 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 dekonstruovat ji v samostatných proměnných.

Můžete také použít typy řazených kolekcí členů místo anonymních typů; Například v dotazech LINQ. Další informace najdete v tématu Volba mezi anonymními typy a typy řazené kolekce č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 metod nástroje. V případě veřejného rozhraní API zvažte definování třídy nebo typu struktury .

Názvy polí řazené kolekce členů

Názvy polí řazené kolekce členů můžete explicitně zadat buď ve výrazu inicializace 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 C# 7.1, pokud nezadáte název pole, může být odvozen z názvu odpovídající proměnné ve výrazu inicializace ř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}.");

To se označuje jako inicializátory projekce řazené kolekce členů. Název proměnné se neprojektuje na název pole řazené kolekce členů v následujících případech:

  • Název kandidáta je název člena typu řazené kolekce členů, například Item3, , ToStringnebo Rest.
  • Název kandidáta je duplikát jiného názvu pole řazené kolekce členů( explicitně nebo implicitně).

V takových případech buď explicitně zadáte název pole, nebo se k poli dostanete podle výchozího názvu.

Výchozí názvy polí řazené kolekce členů jsou Item1a Item3Item2tak dále. Výchozí název pole můžete použít vždy, i když je zadaný název pole 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.

Porovnání rovnosti členů kolekce členů a řazených kolekcí členů nezohlední názvy polí.

Kompilátor v době kompilace nahradí ne výchozí názvy polí odpovídajícími výchozími názvy. V důsledku toho explicitně zadané nebo odvozené názvy polí nejsou v době běhu dostupné.

Tip

Povolte rozhraní IDE řazené pravidlo stylu kódu . NET0037 a nastavte předvolbu pro odvozené nebo explicitní názvy polí řazené kolekce členů.

Přiřazení a dekonstrukce řazené kolekce členů

Jazyk C# podporuje přiřazení mezi typy řazených kolekcí členů, které splňují obě následující podmínky:

  • Oba typy řazených kolekcí členů mají stejný počet prvků.
  • pro každou pozici řazené kolekce členů je typ řazené kolekce členů zprava stejný jako nebo implicitně převést na typ odpovídajícího elementu řazené kolekce členů zleva.

Hodnoty elementů řazené kolekce členů jsou přiřazeny podle pořadí prvků řazené kolekce členů. Názvy polí řazené kolekce členů se ignorují a nepřiřazují, 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

Pomocí operátoru = přiřazení můžete také dekonstruovat instanci kolekce členů v samostatných proměnných. Můžete to udělat jedním z následujících způsobů:

  • Explicitně deklarujte 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.
    
  • Pomocí klíčového var slova mimo závorky deklarujte implicitně zadané proměnné a nechte kompilátor odvodit jejich 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žijte 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 členů řazené kolekce členů

Počínaje jazykem C# 7.3 podporují == typy řazené kolekce členů a != operátory. Tyto operátory porovnávají členy levého operandu s odpovídajícími členy operandu pravé ruky podle 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 != nebere v úvahu názvy polí řazené kolekce členů.

Dvě řazené kolekce členů jsou srovnatelné, pokud jsou splněny obě následující podmínky:

  • Oba řazené kolekce členů mají stejný počet prvků. Například nekompiluje, t1 != t2 pokud t1 a t2 má různá čísla prvků.
  • Pro každou pozici řazené kolekce členů jsou odpovídající prvky z levé a pravé řazené operandy srovnatelné s == operátory a != operátory. Například se nekompiluje, (1, (2, 3)) == ((1, 2), 3) protože 1 není srovnatelná s (1, 2).

!= Operátory porovnávají == řazené kolekce členů ve zkratce. To znamená, že operace se zastaví, jakmile splňuje dvojici nerovných prvků nebo dosáhne konce řazených řazených členů. Před jakýmkoli porovnáním se však vyhodnotí 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 parametry

Obvykle refaktorujete metodu, která má out parametry do metody, která vrací řazenou kolekci členů. Existují však případy, kdy 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

Kolekce členů jazyka C#, které jsou podporovány typy System.ValueTuple , se liší od řazených kolekcí členů, které jsou reprezentovány typy System.Tuple . Hlavní rozdíly jsou následující:

  • System.ValueTuple typy jsou typy hodnot. System.Tuple typy jsou odkazové typy.
  • System.ValueTuple typy jsou proměnlivé. System.Tuple typy jsou neměnné.
  • Datové členy typů System.ValueTuple jsou pole. Datové členy typů System.Tuple jsou vlastnosti.

specifikace jazyka C#

Další informace najdete v následujících poznámkách k návrhu funkcí:

Viz také