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;} со всеми ожидаемыми конструкторами и битами равенства.

Другие вопросы по тегам