IEnumerable <string> в строку

рассмотрим это:

string test = "";
somestring.ToList().Take(50).Select(
    delegate(char x)
    {
        test += x;
        return x;
    }
);

теперь, почему после этого тест пуст? Я не забочусь о возвращении этого, я знаю его IEnumerable.

если это все кажется беспорядочным, тогда как я могу преобразовать IEnumerable<char> в строку?

спасибо заранее.

Ответы

Ответ 1

Потому что вы не выполнили запрос. Линк ленив. Он будет выполнен, если вы выполните либо foreach, либо ToList/ToArray/ToDictionary.

и я советую сделать это так

string test = new string(somestring.Take(50).ToArray());

или даже используя

string test = somestring.Substring(0, 50);

Подробнее об этом. Select предназначен для применения какого-либо преобразования к каждому элементу в последовательности. Эта операция также известна как map. Если вы хотите создать отдельный элемент из последовательности, это Aggregate, aka reduce. Он не ленив, он принудительно выполняет запрос.

Ответ 2

(Другие объяснили, почему это не работает.)

В настоящий момент ваш вопрос не совсем понятен - неясно, имеете ли вы дело с IEnumerable<char> или IEnumerable<string>. (Ваш текст предлагает IEnumerable<string>, ваш код предлагает IEnumerable<char>). Если это IEnumerable<string>, и вы используете .NET 4, это очень просто:

string combined = string.Join("", list.Take(50));

Если вы используете .NET 3.5, все равно довольно легко:

string combined = string.Join("", list.Take(50).ToArray());

Очевидно, используйте что-то вроде ",", если вам нужен разделитель между строками.

Если вы имеете дело с общим IEnumerable<char>, используйте

string combined = new string(chars.Take(50).ToArray());

Если вы на самом деле имеете дело со строкой для начала, используйте Substring:)

Ответ 3

Select возвращает IEnumerable<char>, но вы не перечисляете его в своем коде, чтобы делегат не выполнялся. Если вы измените его на:

string test = "";
somestring.Take(50).Select(
    delegate(char x)
    {
        test += x;
        return x;
    }
).ToList();

Ответ 4

Потому что вы только объявили последовательность, но вы ее не выполнили. Если вы добавили еще один .ToList() в конец, тогда test будет содержать символы в нем.

Однако я настоятельно рекомендую эту практику. Вы используете оценку последовательности, чтобы вызвать побочные эффекты. Вы уже обнаружили, что результаты сбивают с толку. Если вам действительно нужны первые 50 элементов последовательности, просто используйте только Take:

var partSequence = fullSequence.Take(50);

В приведенном выше примере может быть написано что-то вроде этого:

var partString = new string(someString.Take(50).ToArray());

но я уверен, что вы знаете string.Substring() для этой цели.

Ответ 5

Потому что Select ленив, поэтому функция, которую вы передаете, будет оцениваться только после использования результата Select.

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

В этом конкретном случае вы можете просто использовать метод String.Join.