C# 7.0 ValueTuples против анонимных типов
Глядя на новые C# 7.0 ValueTuples, мне интересно, будут ли они полностью заменены Anonymous Types
, Я это понимаю ValueTuples
являются структурами и, следовательно, ведут себя немного иначе, чем Anonymous Types
которые являются классами. Однако я не вижу варианта использования, в котором я бы предпочел использовать Anonymous Type
через ValueTuple
,
Есть ли случаи, когда использование Anonymous Type
будет по-прежнему выгодно использовать ValueTuples
в C# 7.0?
1 ответ
Анонимные типы являются неизменяемыми, кортежи - нет. Это отражается в том, что анонимные типы предоставляют свойства, а кортежи - поля. Привязка данных почти всегда требует свойств.
Большая часть существующего кода работает только со ссылочными типами, но не с типами значений. В частности, на ум приходят проекции в Entity Framework: проекции на типы значений просто не реализуются.
- анонимные типы могут нести данные имени внутрь, но не могут выражать данные имени в подписях
- кортежи значений могут выражать данные имени в подписях, но не могут нести данные имени внутрь
Образец подписи:
(int Id, string Name) GetFoo(...) // could also use tuples in args, but not very useful
Невозможно сделать это с анонимными типами, поскольку вы не можете выразить анонимный тип иначе, как какobject
на подпись.
Пример "внутрь":
под этим я подразумеваю передачу данных имен в библиотеки. Например, если мы рассмотрим JSON:
var json = SomeJsonConvertAPI(new { Id = 42, Name = "abc" });
библиотека сможет видеть имена Id
а также Name
и работайте соответственно (придумывая JSON, например {"Id":42,"Name":"abc"}
); Однако, это не возможно с ценностными кортежей - любой библиотеки, будь то с помощью<T>
или object
или что-то еще, увидит только Item1
, Item2
и т. д. - без механизма получения данных об имени, которые существуют на исходном сайте.
Было бы неплохо, если бы что-то такое же краткое, как кортежи значений и анонимные типы, но которое можно было бы использовать в подписях и передавать внутрь библиотеки; и, таким образом, C# 9 дает вам записи:
record Foo(int Id, string Name);
что является сокращением от class Foo
с членами int Id {get;}
а также string Name {get;}
со всеми ожидаемыми конструкторами и битами равенства.