Comments 8
Это здорово, конечно, но зачем это здесь? Что нового, того что нет в документации, можно узнать из этой публикации?
например я узнал что это не синтаксический сахар , очень был уверен что это он , а тут оказывается разные типы
Во-первых это, конечно, есть в документации. Во-вторых, синтаксис валуетуплов это сахар
А это ты не видел - Tuple Класс (System) | Microsoft Docs
Неделя началась с постов про C#, что ж.
кортежи определяются с неограниченным количеством элементов.
Здесь было бы уместно сказать, что кортеж это просто сахар над System.ValueTuple<...>
. И что у этого есть проблема, такая же как у System.Action
и System.Func
-- конечное число комбинаций.
Так если ваш кортеж/тапл содержит до 7 элементов, под это все выписаны отдельные дженерики (включая кортеж размера 0 и 1, хотя создать их с помощь сахара нельзя).
А дальше начинается фигня, потому что ValueTuple`8
содержит 7 дженерик полей, а 8-ое зарезервировано под такой же кортеж. Поэтому кортеж из 8 элементов это тип, который содержит 7 первых элементов и 8-ой, обернутый в 1-кортеж. А если у вас 10 элементов, то это все равно ValueTuple`8,
но последний элемент это 3-кортеж, и так далее.
См примеры на SharpLab и имплементацию на GitHub.
А еще ваш кортеж реализует ITuple
, такой же интерфейс реализуют и обычные System.Tuple<>
. Поэтому кортежи можно проверять на ITuple
, который имеет длину и индексатор типа object
. Эта фича используется, кстати, при pattern-matching.
Если у вас object o is (int a, int b),
то проверка идет не на ValueTuple
а на интерфейс, а значит и Tuple
тоже подойдет. Конрад Кокоса, кажется, пригорал по этому поводу в одном из твитов, говорил что вместо такого паттерна проще чекать по GetType
и потом явно приводить тип -- получалось быстрее, чем доставать из интерфейса objects и потом каждый распаковывать в нужный тип. Ссылки на твит не найду, но вот ссылка на пример на ShapLab, где видна разница. Не силен в asm
, но кажется даже JIT-код содержит вызовы всяких Unbox
, что вряд ли показатель быстрого кода.
Зато если у вас свой тип реализует ITuple
, он должен честно паттерн-матчистя и деконструироваться (но я не првоерял).
Ах да, в топике про деконструкцию хорошо бы было упомянуть и деконструкцию произвольных типов по сигнатуре public void Deconstruct(out T1 p1, out T2 p2, /* .. */)
. Можно как инстанс метод, можно как экстеншн метод навесить на чужой тип. После этого работает (T1 p1, T2 p2) = myTypeInstance
, ну и весь синтаксический сахар паттернов. Хорошо сочетается с foreach.
Не уверен, что этим кто-то особо пользуется. По крайней мере - в коде разных людей я ValueTuple (как и, в принципе, вообще Tuple) не встречал, да и не вижу смысла в этом. Надо передать функции много параметров? Создай объект. Надо вернуть много результатов? Создай объект или, если нужно просто значение и успешность операции, то верни bool, а через out выведи результат.
Кортежи (tuple) в C#