Представление типизированных N-кортежей в C#

#c# #.net #generics #coding-style

#c# #.net #обобщения #стиль кодирования

Вопрос:

 List<struct {string, string, double} > L = new List<struct {string, string, double}>;
L.Add({"hi", "mom", 5.0});
  

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

На самом деле меня не волнует строгая типизация, но список переменных не работает. Нужен ли мне список объектов? Это самое близкое, что я могу получить?

Определение структур или классов для временных структур данных кажется мне подробным и педантичным.

Комментарии:

1. Слишком много программирования на Lua, возможно, погубило меня.

Ответ №1:

Лучший способ представить это в C # — использовать Tuple тип

 var l = new List<Tuple<string, string, double>>();
l.Add(Tuple.Create("hi", "mom", 42.0));
  

Явной языковой поддержки кортежей нет, но, как вы можете видеть, API не слишком многословен

Комментарии:

1. Вы также могли бы написать метод расширения, чтобы сделать его немного менее многословным. Тогда вы могли бы сделать что-то вроде l.Add(1,2,3);

Ответ №2:

 var arr = new[] { Tuple.Create("hi","mom", 5.0) };
  

самый простой; на самом деле это массив, но список тоже достаточно прост — возможно, .ToList() если вам лень.

Лично в этом сценарии я бы использовал anon-type:

 var arr = new[] { new { Text = "hi", Name = "mom", Value = 5.0 } };
  

Очень похоже, за исключением того, что имена членов более значимы.

Комментарии:

1. Лично я бы здесь тоже предпочел анонимные типы.

Ответ №3:

 List<Tuple<string, string, double>> L = new List<Tuple<string, string, double>>();
L.Add(Tuple.Create("hi", "mom", 5.0));
  

Подробнее о классе Tuple.

Ответ №4:

Вы также можете взглянуть на использование анонимных типов в качестве альтернативы кортежам.

Пример инициализации массива анонимных типов и зацикливания на результате:

 var anons = new [] { new {num=1, str="str1"},
                     new {num=2, str="str2"} };

foreach(var v in anons) Console.WriteLine(v.num   " "   v.str);
  

Комментарии:

1. Проблема в том, что очень сложно объявить a, List<T> когда T это анонимный тип.

2. Если вы используете его только в контексте одного метода, вам не нужно указывать T . Вы могли бы использовать комбинацию var вывода, linq .ToList() и анонимных классов для управления этим.

3. @Gabe: Я знаю, что в OP упоминается список, но я не уверен, что список<T> необходим. Пожалуйста, посмотрите фрагмент кода, который я добавил к своему ответу.

Ответ №5:

Если вы используете C # 4.0, вы можете использовать тип Tuple

Комментарии:

1. Обратите внимание, что он неизменяем, а также придает вам немного странный вид . Свойства Item1, .Item2 и т.д. Для доступа к значению каждого компонента кортежа

Ответ №6:

Вы смотрели на Tuple класс, представленный в .NET 4.0?

Другим вариантом является использование анонимных типов.

Ответ №7:

Самый простой способ, который я могу придумать, — это использовать кортежи:

         var L = new List<Tuple<string, string, double>>();

        L.Add(Tuple.Create("a", "b", 10D));
  

В качестве альтернативы вы также могли бы использовать список dynamics

Комментарии:

1. ExpandoObject возможно, это просто используемый динамический тип.