У нас был некоторый код здесь (в VS2005 и C # 2.0), где предыдущие инженеры старались изо всех сил использовать list.ForEach( delegate(item) { foo;});
вместо foreach(item in list) {foo; };
для всего кода, который они написали. например блок кода для чтения строк из dataReader.
Я до сих пор не знаю точно, почему они это сделали.
Недостатками list.ForEach()
являются:
Это более многословно в C # 2.0. Однако в C # 3 и далее вы можете использовать синтаксис "=>
", чтобы сделать несколько кратких выражений.
Это менее знакомо. Люди, которые должны поддерживать этот код, будут удивляться, почему вы сделали это таким образом. Мне потребовалось некоторое время, чтобы решить, что не было никаких причин, кроме, возможно, чтобы писатель казался умным (качество остальной части кода подрывало это). Он также был менее читаемым, с "})
" в конце блока кода делегата.
См. Также книгу Билла Вагнера «Эффективный C #: 50 конкретных способов улучшить ваш C #», где он рассказывает о том, почему foreach предпочтительнее других циклов, таких как циклы for или while - главное, что вы позволяете компилятору решить, как лучше всего построить цикл. Если будущей версии компилятора удастся использовать более быстрый метод, вы получите его бесплатно, используя foreach и перестройку, а не изменяя свой код.
a foreach(item in list)
позволяет использовать break
или continue
, если вам нужно выйти из итерации или цикла. Но вы не можете изменить список внутри цикла foreach.
Я удивлен, увидев, что list.ForEach
немного быстрее. Но это, вероятно, не веская причина использовать его повсеместно, это было бы преждевременной оптимизацией. Если ваше приложение использует базу данных или веб-сервис, который, а не управление циклом, почти всегда будет находиться там, где время идет. И вы тоже сравнивали его с циклом for
? list.ForEach
может быть быстрее благодаря использованию этого внутри, а цикл for
без обертки будет еще быстрее.
Я не согласен с тем, что версия list.ForEach(delegate)
"более функциональна" в любом значительном смысле. Он передает функцию в функцию, но нет большой разницы в результатах или организации программы.
Я не думаю, что foreach(item in list)
«точно говорит, как вы хотите, чтобы это делалось» - цикл for(int 1 = 0; i < count; i++)
делает это, цикл foreach
оставляет выбор управления за компилятором.
Мне кажется, что в новом проекте использовать foreach(item in list)
для большинства циклов, чтобы придерживаться общего использования и для удобства чтения, и использовать list.Foreach()
только для коротких блоков, когда вы можете сделать что-то более элегантно или компактно с оператором C # 3 "=>
". В подобных случаях уже может существовать метод расширения LINQ, более конкретный, чем ForEach()
. Посмотрите, если Where()
, Select()
, Any()
, All()
, Max()
или один из многих других методов LINQ уже не делают то, что вы хотите из цикла.