C# 7 – Кортежи (обновленный тип Tuple)

C# logo Одно из улучшений C# 7 коснулось работы с кортежами, которые представлены типом Tuple . Ранее их использование было не очень популярно по двум причинам: относительная громоздкость конструкции; низкая читабельность кода из-за стандартных, ни о чем не говорящих имен свойств Item1 … ItemN . Зачастую вместо Tuple создавался отдельный класс, что увеличивало объем кода. В других случаях использовались выходные параметры ( out ), но это делало сами методы неудобными для использования. С# 7 устраняет указанные недостатки. Для примера возьмем код с Tuple и улучшим его:

public Tuple<double, double> GetCoords()
{
    // ...
    return new Tuple<double, double>(valueX, valueY);
}

Использование нового варианта Tuple требует установки NuGet пакета System.ValueTuple. Важно отметить, что старый и новый Tuple это различные типы.

Возможности C# 7 позволяют:

  • использовать сокращенную запись, указав в круглых скобках используемые типы при определении и значения при создании экземпляра Tuple;
  • дополнительно можно задать имена свойств (при этом IntelliSense использует их в подсказках при выборе свойств).
public (double X, double Y) GetCoords()
{
    // ...
    return (valueX, valueY);
}

Обратите внимание на отсутствие ключевого слова new при создании экземпляра Tuple.

При этом дополнительно доступны:

  • обратная совместимость: к свойствам по прежнему можно обращаться по именам Item1ItemN.
  • возможность использования деконструкции для переопределения имен свойств.

Код из примера выше можно использовать следующим образом:

// 1) Используем Item1 ... ItemN  var coords = map.GetCoords0();
this.ProcessCoods(coords.Item1, coords.Item2);
 
// 2) Используем имена свойств
var coords = map.GetCoords2();
this.ProcessCoods(coords.X, coords.Y);
 
// 3) Деконструкция в отдельные переменные с указанием типов
(double x, double y) = map.GetCoords0();
this.ProcessCoods(x, y);
 
// 4) Деконструкция в отдельные переменные с использованием var
var(x, y) = map.GetCoords0();
this.ProcessCoods(x, y);

Обратите внимание, что варианты с деконструкцией (3) и (4) так же можно можно использовать и со старым Tuple.