День двести шестьдесят четвёртый. #ЗаметкиНаПолях
Использование кортежей. Начало
Ранее я уже писал, что в C# 7 упрощён синтаксис использования кортежей. Кортежи можно использовать как параметры методов, переопределять методы, используя кортежи с разными типами и количеством значений, приводить кортежи с разными типами значений, проверять кортежи на равенство и многое другое. Но это не значит, что теперь обязательно их использовать везде. Далее рассмотрим некоторые альтернативы кортежам, их плюсы и минусы.
1. Тип System.Tuple<…>
Типы
Недостатки:
- отсутствие какой-либо языковой интеграции (сложнее для создания, более длинные имена типов, отсутствует поддержка приведений);
- обращаться к элементам можно только по строгим именам вида
- кортежи ссылочного типа ведут себя как полноценные объекты, а не как контейнеры значений, что может быть как хорошо, так и плохо, в зависимости от контекста.
Преимущества:
- копирование ссылки на большой объект
2. Анонимные типы
Анонимные типы были введены как часть LINQ, и это остаётся основным вариантом их использования. Можно использовать их для обычных переменных в методе, но это встречается крайне редко.
Большинство преимуществ анонимных типов также присутствуют в кортежах C# 7: именованные элементы, вывод имени элементов, естественное сравнение и чёткое строковое представление.
Недостатки:
- нельзя вернуть анонимный тип из методов или свойств, не потеряв при этом безопасность типов (использование в типе
Преимущества:
- анонимные типы поддерживаются внешними поставщиками LINQ (для баз данных и т.д.). Литералы кортежей в настоящее время не могут быть использованы в деревьях выражений.
- анонимные типы могут быть более эффективными в некоторых контекстах благодаря передаче по ссылке. Хотя, в большинстве случаев это вряд ли будет проблемой, и тот факт, что кортежи не создают никаких объектов для очистки сборщиком мусора, даёт им преимущество в эффективности.
3. Именованные типы
Кортежи - это просто контейнеры переменных. В них нет инкапсуляции; они не несут никакого значения, кроме того, которое вы подразумеваете при работе с ними. Иногда это именно то, что надо, но остерегайтесь использовать их слишком широко. Рассмотрим кортеж
- двумерные декартовы координаты (x, y)
- двумерные полярные координаты (радиус, угол)
- одномерный отрезок (начало, конец)
- любой другой вариант (тысячи их).
Каждый из этих вариантов использования подразумевает различные операции над ним при моделировании в качестве типа. Вам не нужно беспокоиться о выведении имён элементов или о том, что пользователи случайно используют, например, декартовы координаты в качестве полярных координат. Если вам нужна простая временная группировка значений, кортежи подойдут. Но если вы обнаружите, что вы используете одну и ту же форму кортежа в нескольких местах кода, я бы рекомендовал заменить её на именованный тип.
Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 11.
Использование кортежей. Начало
Ранее я уже писал, что в 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.