#c# #linq
#c# #linq
Вопрос:
Может кто-нибудь объяснить, почему следующая строка C # не ведет себя так же, как следующий каждый блок?
string [] strs = {"asdf", "asd2", "asdf2"};
strs.Select(str => doSomething(str));
foreach(string str in strs){
doSomething(str);
}
Я помещаю точку останова внутри doSomething(), и она не срабатывает при выборе, но это происходит с foreach .
TIA
Комментарии:
1. Вы должны прочитать первые несколько слов раздела примечания в документации .
2. @ChaosPandion Ваш первоначальный комментарий был намного лучше. 😉
3. @Marc — Я хотел быть немного более дипломатичным, поскольку OP может не знать, что означает отложенное или выполнение.
4. @ChaosPandion на самом деле проблема заключается не столько в отложенном выполнении, сколько в том, что он никогда не использует результат своей операции.
5. @ChaosPandion: я предполагаю, что ваше первоначальное утверждение было RTFM 😉 Я прочитал запись MSDN для IEnumerable. Выберите, но не удалось прочитать замечания. Теперь я это вижу. Я понимаю отложенное выполнение. Спасибо за указатель.
Ответ №1:
Это связано с тем, что запросы LINQ откладываются. Лямбда-выражение, переданное Select
методу, фактически выполняется при доступе к результату.
Попробуйте:
string [] strs = {"asdf", "asd2", "asdf2"};
var result = strs.Select(str => doSomething(str));
foreach(var item in result) {
}
Комментарии:
1. единственное, что я хотел бы сказать на это, это то, что я предпочитаю иметь статический список для перебора вместо IEnumerable, если вы собираетесь изменять коллекцию в своем цикле.
Ответ №2:
Linq
Запрос не будет обработан, пока вы не преобразуете его в Enumarable
using ToList()
, ToArray()
, и т.д.
И, кстати, эквивалент вашего foreach
утверждения выглядит примерно так:
строки.ForEach(doSomething);
strs.ToList().ForEach(doSomething);
или
Array.ForEach(strs, doSomething);
Комментарии:
1. Я предполагаю, что вы имеете в виду массив. ForEach(str, doSomething)
2. @dharga, да, это правильно, я обычно делаю ошибки, когда пишу код без тестирования, правильная версия будет либо
strs.ToList().ForEach(doSomething);
илиArray.ForEach(strs, doSomething);
3. .Select() является ленивым. Кроме того, doSomething() должен возвращать значение, поскольку .Select принимает a (a -> b), или, говоря языком .NET, он принимает функцию<..>, а не действие <..> .
Ответ №3:
вам нужно будет сделать что-то вроде
string [] strs = {"asdf", "asd2", "asdf2"};
strs = strs.Select(str => doSomething(str)).ToArray();
foreach(string str in strs){
doSomething(str);
}
Ответ №4:
Я думаю, как только вы используете значения, возвращенные из select, вы увидите вызов doSomething() . Проверьте yield, чтобы понять, почему это происходит.