Будет ли будущая версия .NET поддерживать кортежи на C#?

.Net 3.5 не поддерживает кортежи. Жаль, но не уверен, будет ли будущая версия .net поддерживать кортежи или нет?

.NET 4 поддерживает кортежи msdn.microsoft.com/en-us/library/system.tuple.aspx

M. Dudley 31.08.2011 18:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
69
1
33 194
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

#region tuples

    public class Tuple<T>
    {
        public Tuple(T first)
        {
            First = first;
        }

        public T First { get; set; }
    }

    public class Tuple<T, T2> : Tuple<T>
    {
        public Tuple(T first, T2 second)
            : base(first)
        {
            Second = second;
        }

        public T2 Second { get; set; }
    }

    public class Tuple<T, T2, T3> : Tuple<T, T2>
    {
        public Tuple(T first, T2 second, T3 third)
            : base(first, second)
        {
            Third = third;
        }

        public T3 Third { get; set; }
    }

    public class Tuple<T, T2, T3, T4> : Tuple<T, T2, T3>
    {
        public Tuple(T first, T2 second, T3 third, T4 fourth)
            : base(first, second, third)
        {
            Fourth = fourth;
        }

        public T4 Fourth { get; set; }
    }

    #endregion

А чтобы декларации красивее:

public static class Tuple
{
    //Allows Tuple.New(1, "2") instead of new Tuple<int, string>(1, "2")
    public static Tuple<T1, T2> New<T1, T2>(T1 t1, T2 t2)
    {
        return new Tuple<T1, T2>(t1, t2);
    }
    //etc...
}

Хотя вопрос заключается в том, что MS предоставляет его в .NET 4, на данный момент это хороший способ справиться с этим. +1

Chris Charabaruk 30.09.2008 11:03

Такой подход наследования хорош, если вам не нужно сравнивать два кортежа на равенство. Я хотел реализовать IEquatable <Tuple <T1, T2 >> и т.д. в своей реализации, поэтому я не мог использовать наследование, потому что я не хотел, чтобы Tuple <T1, T2> был равен Tuple <T1, Т2, Т3, Т4>.

Joel Mueller 03.12.2008 21:35

@Joel, Equals может проверить динамический тип обоих аргументов.

RossFabricant 05.04.2009 21:49

Как бы вы использовали это в коде? t = новый кортеж (1, 2); т. во-первых и т. во-вторых?

Andriy Drozdyuk 30.04.2009 04:51

См. Также еще один ответ на аналогичный вопрос: stackoverflow.com/questions/955982/…

Benjol 29.07.2009 10:25

@drozzy, нет, вам нужно будет сделать t = new Tuple <int, int> (1, 2);

Benjol 29.07.2009 10:26

@dimarzionist, извините за редактирование вашего сообщения, я пробовал оставить комментарий, но он не читается, не стесняйтесь удалять или изменять.

Benjol 29.07.2009 10:31

Я вижу, вы используете наследование - вы действительно хотите иметь возможность передавать Tuple<T1,T2,T3> как Tuple<T1,T2>? Скорее всего, нет.

Callum Rogers 19.04.2013 19:44

Если я правильно помню свои уроки информатики, кортежи - это просто данные.

Если вам нужны сгруппированные данные - создайте классы, содержащие свойства. Если вам нужно что-то вроде KeyValuePair, то вот оно.

Точно так же, как операторы if - это просто gotos с блоком операторов. Кортежи хороши, если вы привыкли к ним, а классы кажутся ненужными и громоздкими в определенных случаях ...

Daniel O 10.03.2009 17:08

Если вам не нужно возвращать 5 элементов из функции, то есть. Конечно, вы можете создать собственный общий класс, но синтаксис в C# 7 намного чище и проще.

AustinWBryan 29.04.2018 04:45

Я был бы удивлен - C# - это строго типизированный язык, тогда как кортежи подходят для более динамически типизированных языков. C# со временем становится все более динамичным, но это синтаксический сахар, а не реальный сдвиг в базовых типах данных.

Если вам нужно два значения в одном экземпляре, KeyValuePair <> является достойной заменой, хотя и неуклюжей. Вы также можете создать структуру или класс, которые будут делать то же самое и могут быть расширены.

«C# стал более динамичным» - нет, он стал более неявным / предполагаемым; это все еще полностью статический язык. Однако лучшая динамическая поддержка (для использования классов DLR), скорее всего, станет усовершенствованием языка в будущем.

Marc Gravell 30.09.2008 11:30

Как вы объясните наличие кортежей в F#, Haskell или любом другом строго и статически типизированном языке, который их полностью поддерживает ...?

Greg Beech 30.09.2008 11:39

На мой взгляд, функция анонимных типов - это не кортеж, а очень похожая конструкция. Результатом некоторых запросов LINQ являются коллекции анонимных типов, которые ведут себя как кортежи.

Вот инструкция, которая на лету создает типизированный кортеж :-):

var p1 = new {a = "A", b = 3};

см .: http://www.developer.com/net/csharp/article.php/3589916

C# довольно легко поддерживает простые кортежи с помощью универсальных шаблонов (согласно предыдущему ответу), а с «бормотанием» (одно из многих возможных усовершенствований языка C#) для улучшения вывода типов они могут быть очень и очень мощными.

Как бы то ни было, F# поддерживает кортежи изначально, и, поиграв с ним, я не уверен, что (анонимные) кортежи добавляют много ... то, что вы получаете в краткости, вы быстро теряете очень в ясности кода.

Для кода внутри одного метода существуют анонимные типы; для кода, выходящего за рамки метода, я думаю, что буду придерживаться простых именованных типов. Конечно, если в будущем C# будет проще сделать их неизменяемыми (при этом с ними легко работать), я буду счастлив.

Одно из преимуществ - для таких вещей, как TryParse, где вы можете написать 'valid value = double.TryParse ("1.02")' и назначить несколько возвращаемых значений без каких-либо неуклюжих параметров out. Но в целом я согласен с тем, что чисто позиционные структуры данных - не лучшее дело.

Greg Beech 30.09.2008 11:45

Согласовано - множественные возвращаемые значения - лучший вариант использования кортежей, кроме этого, для кортежей в коде очень мало смысла. Это должно быть условием, а не ограничением, хотя там, где разрешены кортежи. Я думаю, было бы лучше, если бы языки .NET предоставляли способ «разбивать» возвращаемые объекты на несколько значений, а не вводить тип данных кортеж. Что-то вроде { j = ErrorCode, h = ResultObj } = SomeFunction() (где j и h - местные) было бы гораздо полезнее, чем кортежи.

Walt W 07.10.2010 23:07

Реализация классов Tuple или повторное использование классов F# в C# - это только половина дела - они дают вам возможность относительно легко создавать кортежи, но не синтаксический сахар, который делает их такими удобными для использования в таких языках, как F#.

Например, в F# вы можете использовать сопоставление с образцом для извлечения обеих частей кортежа внутри let, например

let (a, b) = someTupleFunc

К сожалению, сделать то же самое с использованием классов F# из C# было бы гораздо менее элегантно:

Tuple<int,int> x = someTupleFunc();
int a = x.get_Item1();
int b = x.get_Item2();

Кортежи представляют собой мощный метод для возврата нескольких значений из вызова функции без необходимости засорять ваш код одноразовыми классами или прибегать к некрасивым параметрам ref или out. Однако, на мой взгляд, без некоторого синтаксического сахара, делающего их создание и доступ более элегантным, они имеют ограниченное применение.

Как насчет анонимных типов?

Chris Charabaruk 01.10.2008 23:49

Это позволяет вам заменить Tuple <int, int> на var, но вы все равно получите три строки кода, а не одну

Chris Ballard 02.10.2008 21:15

Возможно, это то, что мы увидим в C# 4.0. Синтаксический сахар, такой как int a, b = someTupleFunc (); должно быть прекрасно выполнимо на уровне компилятора.

Adam Lassek 11.11.2008 22:14

Чтобы сделать их полезными в хэш-таблице или словаре, вы, вероятно, захотите предоставить перегрузки для GetHashCode и Equals.

Вот мой набор кортежей, они автоматически сгенерированы скриптом Python, поэтому я, возможно, немного переборщил:

Ссылка на репозиторий Subversion

Вам понадобится имя пользователя / пароль, они оба гость

Они основаны на наследовании, но Tuple<Int32,String> не будет сравниваться с Tuple<Int32,String,Boolean>, даже если они имеют одинаковые значения для двух первых членов.

Они также реализуют GetHashCode, ToString и т. д., А также множество небольших вспомогательных методов.

Пример использования:

Tuple<Int32, String> t1 = new Tuple<Int32, String>(10, "a");
Tuple<Int32, String, Boolean> t2 = new Tuple<Int32, String, Boolean>(10, "a", true);
if (t1.Equals(t2))
    Console.Out.WriteLine(t1 + " == " + t2);
else
    Console.Out.WriteLine(t1 + " != " + t2);

Выведет:

10, a != 10, a, True

Но это еще не все. Если это основано на наследовании, я полагаю, вы могли бы написать Tuple<Int32, String> t1 = new Tuple<Int32, String, Boolean>(10, "a", true); и т. д. Я не уверен, есть ли какой-либо сценарий, который это желательно.

nawfal 29.06.2014 12:45

В Общие библиотеки Lokad (конечно, с открытым исходным кодом) есть реализация правильный (не быстрая) Кортеж C#, которая включает следующие необходимые функции:

  • 2-5 неизменяемых реализаций кортежей
  • Правильный атрибут DebuggerDisplayAttribute
  • Правильное хеширование и проверки равенства
  • Помощники для создания кортежей на основе предоставленных параметров (обобщенные типы выводятся компилятором) и расширений для операций на основе коллекций.
  • проверено на производстве.
Ответ принят как подходящий

Я только что прочитал эту статью из журнала MSDN: Построение кортежа

Вот выдержки:

The upcoming 4.0 release of Microsoft .NET Framework introduces a new type called System.Tuple. System.Tuple is a fixed-size collection of heterogeneously typed data.    

Like an array, a tuple has a fixed size that can't be changed once it has been created. Unlike an array, each element in a tuple may be a different type, and a tuple is able to guarantee strong typing for each element.

There is already one example of a tuple floating around the Microsoft .NET Framework, in the System.Collections.Generic namespace: KeyValuePair. While KeyValuePair can be thought of as the same as Tuple, since they are both types that hold two things, KeyValuePair feels different from Tuple because it evokes a relationship between the two values it stores (and with good reason, as it supports the Dictionary class).

Furthermore, tuples can be arbitrarily sized, whereas KeyValuePair holds only two things: a key and a value.


Хотя некоторые языки, такие как F#, имеют специальный синтаксис для кортежей, вы можете использовать новый общий тип кортежей из любого языка. Возвращаясь к первому примеру, мы видим, что хотя и полезны, кортежи могут быть излишне подробными на языках без синтаксиса для кортежа:

class Program {
    static void Main(string[] args) {
        Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
        PrintStringAndInt(t.Item1, t.Item2);
    }
    static void PrintStringAndInt(string s, int i) {
        Console.WriteLine("{0} {1}", s, i);
    }
}

Используя ключевое слово var из C# 3.0, мы можем удалить сигнатуру типа в переменной кортежа, что позволяет сделать код более читаемым.

var t = new Tuple<string, int>("Hello", 4);

Мы также добавили некоторые фабричные методы в статический класс Tuple, что упрощает создание кортежей на языке, поддерживающем вывод типов, например C#.

var t = Tuple.Create("Hello", 4);

В моем .NET Библиотека Sasa с открытым исходным кодом уже много лет используются кортежи (наряду с множеством других функций, таких как полный анализ MIME). Я использую его в производственном коде уже несколько лет.

C# 7 изначально поддерживает кортежи:

var unnamedTuple = ("Peter", 29);
var namedTuple = (Name: "Peter", Age: 29);
(string Name, double Age) typedTuple = ("Peter", 29);

Это работает из коробки, начиная с .NET 4.7, поскольку более старые версии .NET не содержат необходимых структур ValueTuple. Однако вы можете предоставить их, например, с помощью пакета NuGet, такого как ValueTupleBridge.

tm1 08.11.2017 16:07

Теперь у MS есть официальный пакет nuget для требуемых классов кортежей.

user1228 16.03.2018 22:20

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