День двести шестьдесят четвёртый. #ЗаметкиНаПолях

Использование кортежей. Начало

Ранее я уже писал, что в C# 7 упрощён синтаксис использования кортежей. Кортежи можно использовать как параметры методов, переопределять методы, используя кортежи с разными типами и количеством значений, приводить кортежи с разными типами значений, проверять кортежи на равенство и многое другое. Но это не значит, что теперь обязательно их использовать везде. Далее рассмотрим некоторые альтернативы кортежам, их плюсы и минусы.

1. Тип System.Tuple<…>

Типы System.Tuple<…> в .NET 4 являются неизменяемыми ссылочными типами, хотя типы элементов в них могут быть изменяемыми.

Недостатки:

- отсутствие какой-либо языковой интеграции (сложнее для создания, более длинные имена типов, отсутствует поддержка приведений);

- обращаться к элементам можно только по строгим именам вида ItemX;

- кортежи ссылочного типа ведут себя как полноценные объекты, а не как контейнеры значений, что может быть как хорошо, так и плохо, в зависимости от контекста.

Преимущества:

- копирование ссылки на большой объект Tuple<…> более эффективно, чем копирование значимых типов кортежей ValueTuple<…>, которое включает в себя копирование всех значений элементов. Это также влияет на безопасную многопоточность: копирование ссылки является атомарным, тогда как копирование кортежа ValueTuple - нет.



2. Анонимные типы

Анонимные типы были введены как часть LINQ, и это остаётся основным вариантом их использования. Можно использовать их для обычных переменных в методе, но это встречается крайне редко.

Большинство преимуществ анонимных типов также присутствуют в кортежах C# 7: именованные элементы, вывод имени элементов, естественное сравнение и чёткое строковое представление.

Недостатки:

- нельзя вернуть анонимный тип из методов или свойств, не потеряв при этом безопасность типов (использование в типе dynamic).

Преимущества:

- анонимные типы поддерживаются внешними поставщиками LINQ (для баз данных и т.д.). Литералы кортежей в настоящее время не могут быть использованы в деревьях выражений.

- анонимные типы могут быть более эффективными в некоторых контекстах благодаря передаче по ссылке. Хотя, в большинстве случаев это вряд ли будет проблемой, и тот факт, что кортежи не создают никаких объектов для очистки сборщиком мусора, даёт им преимущество в эффективности.



3. Именованные типы

Кортежи - это просто контейнеры переменных. В них нет инкапсуляции; они не несут никакого значения, кроме того, которое вы подразумеваете при работе с ними. Иногда это именно то, что надо, но остерегайтесь использовать их слишком широко. Рассмотрим кортеж (double, double). Он может быть использован как:

- двумерные декартовы координаты (x, y)

- двумерные полярные координаты (радиус, угол)

- одномерный отрезок (начало, конец)

- любой другой вариант (тысячи их).

Каждый из этих вариантов использования подразумевает различные операции над ним при моделировании в качестве типа. Вам не нужно беспокоиться о выведении имён элементов или о том, что пользователи случайно используют, например, декартовы координаты в качестве полярных координат. Если вам нужна простая временная группировка значений, кортежи подойдут. Но если вы обнаружите, что вы используете одну и ту же форму кортежа в нескольких местах кода, я бы рекомендовал заменить её на именованный тип.



Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 11.