2014-12-17 3 views
1

LINQ, кажется, добавляет свой индекс (с использованием 2-параметрической перегрузки до .Select; я предполагаю, что LINQ генерирует индекс, поскольку словари не имеют ни одного) целым числом с использованием конкатенации строк, а не сложения.Почему LINQ обрабатывает свой индекс как строку?

Следующий код возвращает myStr_3, myStr_13, myStr_23, т.е. добавляет индекс словаря i и число count, как если бы они были строками, так 1 + 3 становится 13, а не 4:

// myDictionary is <string, object> 
int parmCount = parameters.Count; // 3 
int count = parmCount; // Closure safety 
var setValues = myDictionary.Select((d, i) => "myStr_" + i + count); 

Видимо индекс 0 эквивалентно пустой строке, а не «0». Weird.

Следующий код (обратите внимание на дополнительные параметры) возвращает правильные результаты; myStr_3, myStr_4, myStr_5:

int parmCount = parameters.Count; // 3 
int count = parmCount; 
var setValues = myDictionary.Select((d, i) => "myStr_" + (i + count)); 

Update: Так "myStr_" + i полученные «правильные результаты», я прыгнул к выводу, что использование дополнительной целочисленной переменной в настоящее время обрабатываются неправильно, не задумываясь о том, как i использовался. Поведение LINQ, конечно, совершенно правильно. Мне просто нужно прекратить публиковать вопросы, когда я устал.

MSDN says:

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

Хотя тип индекса не указан, это для меня, а слово «индекс» означает числовой тип.

Почему LINQ добавляет два целых числа, как если бы они были строками?

+0

вы можете опубликовать воспроизводимый пример? [Я не могу воспроизвести его в данный момент] (https://dotnetfiddle.net/j6vjpG) –

+0

Ваш первый код должен выдавать выходные данные, такие как 'myStr_03', а не' myStr_3' – Habib

+0

@Habib Вы правы. См. Ответ на Selman22 ниже. Этот вопрос не был моим лучшим на SO. :) –

ответ

2

Почему LINQ добавляет два целых числа, как если бы они были строками?

Это не LINQ, но конкатенация, если у вас есть string + int + int без (), все будет рассматриваться как string, как ToString метод будет вызываться для каждого операнда.

Это:

"myStr_" + i + count 

превращается в нечто вроде:

string.Concat("myStr_",i,count); 

, который внутренне вызывает, ToString на каждого параметра.

Но когда у вас есть код:

"myStr_" + (i + count) 

Тогда из-за скобкой, имеющего более precedence that + operator. целочисленная арифметика выполняется для i и count, а затем их результат объединяется в строке.

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

См: Dictionary C#

Для целей перечисления, каждый элемент в словаре трактуются как структуру KeyValuePair, представляющих значение и его ключа. Порядок, в котором возвращаются элементы, не определен.

EDIT: за комментарий:

я считал это, но: .Select ((d, я) => "myStr_" + я); (нет бесплатного счетчик переменных). дополнение, а не конкатенация строк.

Это еще конкатенация строк. Вы видите измененное значение i из-за Select. На каждом перечислении значение i является индексом элемента, так что вы получите что-то вроде:

"myStr_" + 0 
"myStr_" + 1 
"myStr_" + 2 
"myStr_" + 3 
..... 

Опять же, это значение i может измениться для того же самого элемента, так как словари не упорядочены коллекций.

См. Enumerable.Select перегрузка, которая предоставляет индекс.

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

+1

@CharlesBurns, который все еще выполняет конкатенацию строк, но это просто, что в каждом перечислении значение 'i' увеличивается с помощью' Select' – Habib

+0

, стоит отметить, что '' myStr_ "+ (i + count)' оценивает 'i + count', потому что скобки имеют более высокий приоритет, чем' + ' –

+0

Я это рассматривал, но все запутался, когда использование JUST в индексе создало то, что я считал правильными результатами. Теперь, когда я думаю об этом, я просто не очень внимательно рассматривал, что происходит, только используя индекс. Глупая ошибка. –

Смежные вопросы