Являются ли анонимные типы С# избыточными в С# 7
Поскольку С# 7 вводит кортежи значений, существует ли осмысленный сценарий, где они лучше подходят, чем кортежи?
Например, следующая строка
collection.Select((x, i) => (x, i)).Where(y => arr[y.i].f(y.x)).ToArray();
делает следующую строку
collection.Select((x, i) => new {x, i}).Where(y => arr[y.i].f(y.x)).ToArray();
избыточными.
Какой будет вариант использования, когда лучше использовать его по другому (по соображениям производительности или оптимизации)?
Очевидно, что если требуется более шести полей, кортежи не могут использоваться, но есть ли что-то более нюансированное ему?
Ответы
Ответ 1
Существуют различные различия между анонимными типами и кортежами С# 7, которые могут или не могут сделать более подходящим, чем другие в определенных ситуациях:
- С# 7 кортежей
ValueTuple<>
s. Это означает, что они являются типами значений, тогда как анонимные типы являются ссылочными типами.
- Кортежи допускают статическое типирование во время компиляции, так как они являются типом, который может быть явно выражен. Таким образом, вы можете использовать их как аргументы метода, возвращаемые типы и т.д.
- Члены анонимного типа являются действительными свойствами, которые существуют в типе. Элементы Tuple - это поля.
- Свойства анонимного типа имеют фактическое имя, а поля в кортеже называются только
ItemN
(для чисел N
). Этикетки - это только метаданные, которые в основном используются компилятором и не сохраняются с фактическим кортежем.
- Поскольку создание анонимного типа фактически создает тип под капотом, у вас есть уровень безопасности с ними. Поскольку кортежи представляют собой только общие контейнеры с аргументами прикладного типа, у вас нет полной безопасности с ними. Например, кортеж
(int, int)
для размера будет полностью совместим с кортежем (int, int)
для позиции, в то время как анонимные типы полностью закрыты.
- Как отметил Джон Скит, синтаксис С# 7 кортежа в настоящее время не поддерживается в деревьях выражений.
Ответ 2
Текущий ответ от @poke является правильным и отмечает различия между кортежем и анонимными типами. Я собираюсь обсудить, почему вы все еще используете их или предпочитаете друг друга.
Есть две новые функции С# 7, которые удаляют анонимные типы. ValueTuples и Записи.
Основная причина, по которой вы не используете анонимные типы, -
- вы не можете использовать анонимные типы по всему миру, и они только безопасны для использования при локальном использовании. не являясь локальным, вы должны рассматривать его как объект
dynamic
, который имеет значительные служебные накладные расходы.
Причины, по которым вы предпочитаете кортеж над анонимными типами.
-
они безопасны во всем мире. (независимо от наименования)
-
они могут использоваться в качестве аргументов метода, типа аргументов, полей и почти везде. (да, я сказал довольно много, есть места, которые нужно принимать с кортежами, вопрос времени).
-
так как они могут использоваться как аргумент типа, вы, вероятно, предпочитаете обернуть легкий набор параметров в один параметр. как Stack<(min, mid, max)>
-
вы можете изменять наименования элементов, когда вы считаете их подходящими, в общем имени контекста item
может удовлетворяться, и в более конкретном контексте вам также требуется более конкретное имя, например car
-
они неявно конвертируемы, int, int
может быть назначен (int, long)
без явного приведения.
-
они используются в Deconstruct s. который приносит много синтаксического сахара на язык.
-
вы можете иметь несколько назначений и объявлений, например (int x, int y) = (0, 1)
Имея все эти функции, есть еще одна причина, по которой вы можете предпочесть анонимный тип над кортежем.
- Анонимные типы - это ссылочный тип, но кортежи - это тип значения.
но что, если вы хотите использовать анонимный тип во всем мире? вы предпочитаете иметь динамические объекты или статически типизированные объекты?
Функция входящих записей снова поражает анонимные типы. с записями вы определяете свой класс коротким, кратким и удобным способом. не ахти какое дело. всего одна строка
public class Point(X, Y);
Надевайте безопасность на все места, и у вас также есть ссылочный тип в руке. эти две новые функции приносят все, чтобы победить анонимные типы.
Обратите внимание, что записи еще не добавлены, нам просто нужно подождать.
Только оставшееся реальное использование анонимных типов будет
-
они все еще служат функцией обратной совместимости
-
они могут использоваться в запросах Linq при локальном использовании анонимного типа. поэтому я не говорю, что анонимные типы являются избыточными.
Как я уже сказал, ValueTuples еще не совместимы с каждым компонентом. это просто вопрос времени, но так будет и в будущем.
достаточно аргументов. по моему скромному мнению использование анонимных типов становится редкими, старые программисты могут по-прежнему использовать анонимный тип в Linq по привычке.