Как правильно назначить имена именованным кортежам в списке - PullRequest
0 голосов
/ 20 июня 2019

У меня есть следующий код, и он, кажется, работает нормально, но когда я проверяю кортежи внутри списка, они называются Item1, Item2, Item3 вместо имен, которые я им присвоил.Что я делаю неправильно?(Код ссылается на System.ValueTuple.)

Спасибо за вашу помощь.

var listContent = new List<(string date, double value, DateTime datetime)>();

// Read the file just created and put values in list of tuples
using (var reader = new StreamReader(rawFileName))
{
   while (!reader.EndOfStream)
   {
      var line = reader.ReadLine();
      var values = line.Split(',');
      listContent.Add((date: values[0],
         value: Convert.ToDouble(values[2]),
         datetime: DateTime.ParseExact(values[0], "yyyy-MM-dd", null)));
    }
}

Если я поставлю точку останова сразу после приведенного выше кода, в Immediate Window я могу сделать следующее, что еще более озадачивает:

listContent[0]
("2017-01-01", 17.193, {01/01/2017 00:00:00})
    date: "2017-01-01"
    value: 17.193
    datetime: {01/01/2017 00:00:00}
    Raw View: ("2017-01-01", 17.193, {01/01/2017 00:00:00})
listContent[0].Item1
null
listContent[0].date
null
listContent[0].dummy
error CS1061: '(string date, double value, DateTime datetime)' does not contain a definition for 'dummy' and no accessible extension method 'dummy' accepting a first argument of type '(string date, double value, DateTime datetime)' could be found (are you missing a using directive or an assembly reference?)

[ОБНОВЛЕНИЕ]

Я упростил код:

var listContent = new List<(string str1, string str2)>();
for (var n = 1; n < 100; n++)
{
   var tpl = (str1: "hello" + n.ToString(), str2: "world" + n.ToString());
   listContent.Add(tpl);
}
var z = listContent[0].str1;

и проверюиз того, что дает мне непосредственное окно:

z
"hello1"
listContent[0].str1
null

Так что я не схожу с ума: кортежи назначены правильно, но по какой-то причудливой причине немедленное окно все еще дает мне ноль для listContent [0] .str1???

1 Ответ

2 голосов
/ 20 июня 2019

Имена элементов кортежа не являются частью типа. Компилятор переводит имя в соответствующее свойство ItemN.

За исключением локальных переменных (к которым нельзя применять атрибуты), имена передаются в атрибуте [TupleElementNames]. Например, если вы объявите listContents как поле, к нему будет применен следующий атрибут:

[TupleElementNames(new string[] { "date", "value", "datetime" })]

Когда вы наводили курсор мыши на listContents, отладчик видел только экземпляр списка и экземпляры кортежа внутри него. Для данного экземпляра имена элементов кортежа недоступны. Вам понадобятся сопровождающие PropertyInfo, FieldInfo или ParameterInfo, чтобы вы могли получить TupleElementNamesAttribute, который передает имена. Однако, если вы сделали это полем, отладчик по-прежнему смотрит только на экземпляр.

Я не могу объяснить поведение в окне Immediate, и в окне Watch, похоже, возникла та же проблема. Похоже, вы нашли ошибку в Visual Studio.

...