Есть ли способ использовать класс Tuple, но указать имена элементов в нем?
Например:
public Tuple<int, int, int int> GetOrderRelatedIds()
Это возвращает идентификаторы для OrderGroupId, OrderTypeId, OrderSubTypeId и OrderRequirementId.
Было бы хорошо, чтобы пользователи моего метода знали, что есть что. (Когда вы вызываете метод, результаты являются result.Item1, result.Item2, result.Item3, result.Item4. Не ясно, какой из них какой.)
(Я знаю, что мог бы просто создать класс для хранения всех этих идентификаторов, но если эти идентификаторы уже имеют свои собственные классы, в которых они живут, и создание класса для возвращаемого значения этого одного метода кажется глупым.)
Tuple
это очень универсально, так что это все, что ты получаешьОтветы:
В C # 7.0 (Visual Studio 2017) есть новая конструкция, которая делает это:
источник
List<(int first, int second)>
. Мне пришлось загрузить пакет System.ValueTuple из NuGet, чтобы он работал в Visual Studio 2017.return (first: first, middle: middle, last: last);
return (first, middle, last);
в .NET 4.7.1 (не уверен в 4.7.0)ValueTuple
, как правило, большой, является изменяемым типом значения (struct), аTuple
является неизменным ссылочным типом (class). Насколько я знаю, нет способа получить ссылочный типTuple
с понятными именами элементов.До C # 7.0 не было никакого способа обойтись без определения собственного типа.
источник
Вот слишком сложная версия того, что вы спрашиваете:
Почему бы просто не сделать урок?
источник
Tuple<T, T2>
вас, вы не можете быть структурой.С .net 4 вы, возможно, могли бы взглянуть на
ExpandoObject
, однако, не использовать его в этом простом случае, поскольку ошибки во время компиляции становятся ошибками во время выполнения.Стоит упомянуть еще один анонимный тип внутри метода , но вам нужно создать класс, если вы хотите его вернуть.
источник
Воспроизведение моего ответа из этого поста, так как он лучше подходит здесь.
Начиная с C # v7.0, теперь можно присваивать имена свойств кортежа, которые ранее использовались по умолчанию, предопределенным именам
Item1
,Item2
таким как и так далее.Называя свойства Tuple Literals :
Вывод на консоль:
Возврат кортежа (с именованными свойствами) из метода :
Вывод на консоль:
Создание списка кортежей с именованными свойствами
Вывод на консоль:
Я надеюсь, что я охватил все. В случае, если есть что-то, что я пропустил, пожалуйста, дайте мне отзыв в комментариях.
Примечание . В моих фрагментах кода используется функция интерполяции строк C # v7, как подробно описано здесь .
источник
MichaelMocko ответил отлично,
но я хочу добавить несколько вещей, которые я должен был выяснить,
выше линии даст вам ошибку времени компиляции, если вы используете .net framework <4.7
Так что если у вас есть проект, который использует .net Framework <4.7, и вы все еще хотите использовать ValueTuple, то workAround будет устанавливать этот пакет nuget
источник
Нет, вы не можете назвать членов кортежа.
Промежуточным звеном будет использование ExpandoObject вместо Tuple.
источник
Если типы ваших предметов различны, вот класс, который я сделал, чтобы получить их более интуитивно.
Использование этого класса:
Исходный код:
источник
Это очень раздражает, и я ожидаю, что будущие версии C # решат эту проблему. Я считаю, что проще всего использовать другой тип структуры данных или переименовать «элементы» для вашего здравого смысла и для здравомыслия других, читающих ваш код.
источник
Я думаю, что я создал бы класс, но другой альтернативой являются выходные параметры.
Поскольку ваш кортеж содержит только целые числа, вы можете представить его с помощью
Dictionary<string,int>
но я тоже не рекомендую.
источник
Почему все делают жизнь такой сложной? Кортежи предназначены для достаточно временной обработки данных . Постоянная работа с Tuples усложнит понимание кода в какой-то момент. Создание классов для всего может в конечном итоге раздуть ваш проект.
Речь идет о балансе, однако ...
Кажется, ваша проблема - это то, для чего вы хотели бы получить урок. И просто для полноты, этот класс ниже также содержит конструкторы.
Это правильный шаблон для
Или, если вы хотите действительно просто: вы также можете использовать инициализаторы типов:
источник
Я бы написал имена элементов в сводке ... поэтому, наведя указатель мыши на функцию helloworld (), текст скажет hello = Item1 и world = Item2
источник
Просто чтобы добавить в ответ @MichaelMocko. На данный момент у кортежей есть пара ошибок:
Вы не можете использовать их в деревьях выражений EF
Пример:
Это не удастся скомпилировать с ошибкой «Дерево выражений может не содержать литерал кортежа». К сожалению, API деревьев выражений не был расширен за счет поддержки кортежей, когда они были добавлены в язык.
Отслеживание (и повышение) этой проблемы для обновлений: https://github.com/dotnet/roslyn/issues/12897
Чтобы обойти проблему, вы можете сначала привести ее к анонимному типу, а затем преобразовать значение в кортеж:
Другой вариант - использовать ValueTuple.Create:
Ссылки:
https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html
Преобразование анонимного типа в новый тип кортежа C # 7
Вы не можете деконструировать их в лямбдах
Есть предложение добавить поддержку: https://github.com/dotnet/csharplang/issues/258
Пример:
Ссылки:
Они не будут сериализоваться
Имена полей кортежей доступны только во время компиляции и полностью стираются во время выполнения.
Ссылки:
источник
Вы можете написать класс, который содержит кортеж.
Вам необходимо переопределить функции Equals и GetHashCode
и операторы == и! =.
вернется:
Правда
Правда
источник
Пример кортежа C # 7
источник