Кортежи (tuple) в C#

Кортежи появились в C# начиная с версии 7.0 с целью обеспечения работы с наборами значений. Основное предназначение кортежей - обобщение нескольких элементов в структуру с упрощенным синтаксисом. Для использования кортежей необходим тип System.ValueTuple. Для использования кортежей в более ранних версиях .NET Framework в проект необходимо добавить NuGet пакет SystemValueTuple.

Основные свойства кортежей:

  • кортежи определяются с неограниченным количеством элементов.

  • Кортежи являются типом значений.

  • Кортежи поддерживают операторы = и !=

  • Значения кортежей являются общедоступными полями.

var tuple1 = (10, 23.4); //Определен кортеж tuple1 с двумя значениями 10 и 23.4

Обращение к значениям кортежа происходит через поля с названиями типа Item[номер], где номер - порядковый номер значения в кортеже. Рассмотрим на примере программы:

static void Main(string[] args)
{
  int tuple1 = (11, 33);						//Определение кортежа с целочисленными значениями
  Console.WriteLine(tuple1.Item1);	//Вывод на консоль 11
  tuple1.Item2 *= 2;								//Умножение второго значения на 2
}

Возможно определение типа для каждого из значений. Для этого перед именем кортежа в скобках указываются типы для каждого значения.

(string, int) tuple = ("Coin", 25);

Для каждого значения кортежа предусмотрена возможность индивидуального именования. Заданное имя элемента называется именем кандидата. Оно является дубликатором другого явного или неявного имени поля кортежа.

var tuple1 = (purchase:5, sale:10);
Console.WriteLine(tuple1.purchase);

Для определения кортежей можно применять переменные, с которыми в дальнейшем можно производить операции.

var (purchase, sale) = (5, 10);
Console.WriteLine(Purchase);

Применение кортежей

Кортежи могут передаваться в метод в качестве параметров и служить возвращаемым результатом. В частности, очень удобно возвращать кортеж в качестве результата в том случае, если метод возвращает только одно значение.

static void Main(string[] args)
{
    var tuple1 = Method();					//Присваиваем кортежу tuple1 возвращаемое значение
    Console.WriteLine(tuple1.Item1);
    Console.WriteLine(tuple1.Item2);     
}
private static (int, int) Method()	//Метод, возвращающий кортеж
{
    var res = (5, 10);
    return res;
}

В следующем примере кортеж передается в метод в качестве параметра.

static void Main(string[] args)
{
  var (purchase, sale) = Method ((5, 10), 3);
  Console.WriteLine($"Purchase: {purchase} Sale: {sale}");
}

private static (int purchase, int sale) Method((int p, int s)tuple, int n)
{
  var res = (purchase: tuple.p, sale: tuple.s + n);
  return result;
}

Присваивание кортежей

В кортежах предусмотрена возможность присваивания. Для этого оба кортежа должны иметь одинаковое количество элементов, типы соответствующих значений должны совпадать или иметь возможность неявного приведения друг к другу. Значения присваиваются в порядке их расположения. При присвоении имена полей не учитываются.

(int, int) tuple1 = (22, 12);
(double A, double B) tuple2 = (2.15, 3,02);
tuple2 = tuple1;

Деконструкция кортежей

Деконструкцией кортежей называется операция присваивания экземпляра кортежа в отдельные переменные.

var tuple = ("Alex", 36);
(string name, int age) = tuple;
//или
string name;
int age;
(name, age) = tuple;

Проверка кортежей на равенство

var tuple1 = (23, 36);
var tuple2 = (17, 31);
Console.WriteLine(tuple1 == tuple2);
Console.WriteLine(tuple1 != tuple2);

Имена полей кортежей при сравнении не учитываются.

Условия возможности сравнения кортежей:

  • Оба кортежа содержат одинаковое количество элементов.

  • Элементы должны соответствовать возможности сравнения.

Кортежи в качестве параметров вывода

При выполнении рефакторинга метода, имеющего параметры out они могут иметь тип кортежа.

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}");
}

Различия между типами кортежей System.ValueTuple и SystemTuple

Основные различия заключаются в следующем:

  • Типы ValueTuple являются типами значений - типы Tuple - ссылочные типы.

  • Типы ValueTuple являются изменяемыми типами - типы Tuple - неизменяемые.

  • Значениями типов ValueTuple являются поля. Значениями типов Tuple являются свойства.

Список использованных источников:

Tags:
кортежи, C#

You can't comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author's username will be hidden by an alias.