Почему мы не можем давать имена свойствам в кортежах?

Есть ли конкретная причина, по которой мы должны ссылаться на свойства в кортеже как Item1, Item2 и т. Д. Мне это кажется плохой идеей, поскольку они могут легко запутаться в вашем коде. Разве не было бы более значимым иметь возможность называть свои свойства, т.е. Красный, зеленый, синий?


person Paul Matthews    schedule 12.09.2012    source источник
comment
Причина, по которой вы не можете этого сделать, заключается в том, что для этого потребуется изменить язык, чтобы вы могли произвольно переименовывать свойства данного типа или предоставить особую поддержку кортежам.   -  person Lee    schedule 12.09.2012
comment
@spender - Нет, не похоже на написание класса   -  person Paul Matthews    schedule 12.09.2012
comment
@Lee - Ну да, вам придется сменить язык, чтобы он заработал. Но похоже, что именно так это и должно было быть реализовано в первую очередь.   -  person Paul Matthews    schedule 12.09.2012
comment
@Paul - я так не думаю - элементы в кортеже имеют только позиции, а не имена. Было бы неплохо, если бы они добавили поддержку деструктуризации кортежей, например, var (first, second) = tupleInstance. Как бы то ни было, работать с кортежами не намного проще, чем с анонимными классами.   -  person Lee    schedule 12.09.2012
comment
Проголосуйте за эту функцию здесь: visualstudio. uservoice.com/forums/121579-visual-studio-2015/   -  person John    schedule 06.04.2016
comment
@Abatonime Я проголосовал за эту функцию, спасибо   -  person Paul Matthews    schedule 18.05.2016
comment
Мы можем - Лучшее именование в классах Tuple, чем «Item1», «Item2»   -  person RBT    schedule 30.05.2018


Ответы (6)


Если вам нужны имена, не используйте кортежи.

Анонимный тип:

var t = new { Green = 1, Red  = "nice" };

if (t.Green > 0) ....
person Henk Holterman    schedule 12.09.2012

Классы Tuple ‹...> - это обычные классы C #. C # не предоставляет возможности иметь свойства с динамическими именами (кроме использования словаря или динамического объекта, такого как ExpandoObject). Однако C # предоставляет что-то вроде того, что вы хотите, через анонимные типы:

var x = new { Red = 10, Blue = 20, Green = 30 }
var sum = x.Red + x.Blue + x.Green;

Причина, по которой работают анонимные типы, заключается в том, что они представляют собой просто удобный синтаксис для определения настраиваемого класса кортежа на лету.

Они имеют то преимущество, что действуют как именованные кортежи, но имеют недостаток, заключающийся в том, что программист не может именовать их (поэтому вы не можете создать метод, который явно возвращает анонимный тип).

person ChaseMedallion    schedule 12.09.2012

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

person Ben Robinson    schedule 12.09.2012
comment
По моему опыту, кортежи в C # используются ленивыми программистами. Мусор Item1, Item2, Item3 ... вызывает всевозможные проблемы с обслуживанием кода. Я довольно часто наставляю новых сотрудников там, где работаю, и категорически не рекомендую использовать кортежи в коде C #. Я всегда говорю им создать класс с соответствующими названиями свойств, как вы предложили. Я видел код с тремя различными типами кортежей, в которых я работаю. Отладка этого кода - кошмар. - person Mark; 05.06.2016

Кортеж не должен содержать никаких значимых свойств. Это просто одноразовый набор предметов, собранных вместе в группу.

Если вам нужны осмысленные имена свойств, создайте тип с этими свойствами. Вы можете либо написать класс с нуля и использовать этот класс, либо использовать анонимные типы .

person BoltClock    schedule 12.09.2012
comment
Жалко, что C # не предлагает никакого синтаксического сахара для написания такого класса без шаблона. - person CodesInChaos; 12.09.2012
comment
Таким образом, мораль этой истории состоит в том, чтобы взять значения из кортежа и сохранить их в полях с осмысленным именем. В противном случае вы получите Item1, Item7, 1tem3, происходящие во всем вашем коде. Фу! - person Paul Matthews; 12.09.2012
comment
Вам всегда нужно работать с кортежем с самого начала (т. Е. Вы используете API, который возвращает кортеж)? - person BoltClock; 12.09.2012
comment
Нет, я думаю, я просто говорю о методах в моем собственном коде, которые возвращают несколько значений. Просто кажется излишним писать класс для одного или двух методов, которые делают это, когда в этих данных нет ничего особенного. - person Paul Matthews; 12.09.2012

Вы можете определить такой класс (с универсальными шаблонами), если вы всегда будете неравнодушны к Red / Blue, в противном случае вы можете использовать анонимные типы, как предлагали другие.

    class RedBluePair<T1, T2>
    {
        private T1 _Red;
        private T2 _Blue;

        public RedBluePair(T1 red, T2 blue)
        {
            _Red = red;
            _Blue = blue;
        }

        public T1 Red { get { return _Red;} }

        public T2 Blue { get { return _Blue;} }
    }
person Jason    schedule 12.09.2012

Воспроизведение моего ответа из этого сообщения, поскольку теперь можно давать имена свойствам в кортежах.

Начиная с C # v7.0, теперь можно присвоить свойствам кортежа, которые раньше использовались по умолчанию, такие имена, как Item1, Item2 и так далее.

Именование свойств кортежных литералов:

var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa");
Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}");

Вывод на консоль:

Имя - RBT_Yoga, Возраст - 22, Страсть - Доса

Возвращение кортежа (имеющего именованные свойства) из метода:

static void Main(string[] args)
{
    var empInfo = GetEmpInfo();
    Console.WriteLine($"Employee Details: {empInfo.firstName}, {empInfo.lastName}, {empInfo.computerName}, {empInfo.Salary}");
}

static (string firstName, string lastName, string computerName, int Salary) GetEmpInfo()
{
    //This is hardcoded just for the demonstration. Ideally this data might be coming from some DB or web service call
    return ("Rasik", "Bihari", "Rasik-PC", 1000);
}

Вывод на консоль:

Сведения о сотруднике: Rasik, Bihari, Rasik-PC, 1000

Создание списка кортежей с именованными свойствами

    var tupleList = new List<(int Index, string Name)>
    {
        (1, "cow"),
        (5, "chickens"),
        (1, "airplane")
    };

foreach (var tuple in tupleList)
    Console.WriteLine($"{tuple.Index} - {tuple.Name}");

Вывод на консоль:

1 - корова 5 - куры 1 - самолет

Надеюсь, я все рассказал. В случае, если есть что-то, что я пропустил, пожалуйста, оставьте мне отзыв в комментариях.

Примечание. В моих фрагментах кода используется функция интерполяции строк C # v7, как подробно описано здесь.

person RBT    schedule 30.05.2018