Использовать атрибуты для кортежей значений

В С# 7.0.NET вводит новые типы кортежей возвращаемого значения (функциональное программирование), поэтому вместо:

[NotNull]
WrapperUser Lookup(int id)

Я хотел бы использовать кортежи значений:

(User, Info) Lookup(int id)

И я хочу использовать атрибуты для этих типов возврата:

([NotNull] User, [CanBeNull] Info) Lookup(int id)

Но VS2017 не позволяет мне это делать. Как использовать атрибуты без использования класса-оболочки?

Ответ 1

Вы не можете.

(User, Info) Lookup(int id)

- это просто синтаксический сахар для

ValueTuple<User,Info> Lookup(int id)

Параметры типа ValueTuple не являются допустимыми целями для атрибутов. Ваш единственный вариант, кроме класса-оболочки, заключается в том, чтобы обернуть параметры типа в NonNullable wrapper

(NonNullable<User>,NonNullable<Info>) Lookup(int id)

который позволяет использовать его как обычный ValueTuple, например

(NonNullable<User>,NonNullable<Info>) Lookup(int id) => (new User(), new Info());
(User user, Info info) = Lookup(5);

В противном случае вы можете привязать пользовательский атрибут к целому ValueTuple, указывающему, какие элементы кортежа могут быть null с массивом, например TupleElementNamesAttribute, который используется для назначения имен элементам кортежа. Вам нужно будет написать свой собственный визуальный студийный/resharper-плагин, который сделает работу, хотя.