Выражение лямбда с использованием предложения Foreach
Возможный дубликат:
Почему в интерфейсе IEnumerable нет метода расширения ForEach?
ИЗМЕНИТЬ
Для справки, здесь сообщение в блоге, которое eric ссылается на комментарии
http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx
ORIG
Больше любопытства, я полагаю, но один для Savants Specification С#...
Почему предложение ForEach() не работает (или недоступно) для использования в наборах результатов IQueryable/IEnumerable...
Вы должны сначала преобразовать результаты ToList() или ToArray()
Предположительно, это техническое ограничение на то, как С# выполняет итерацию IEnumerables Vs. Списки...
Это как-то связано с отложенным выполнением IEnumerables/IQuerable Collections.
например.
var userAgentStrings = uasdc.UserAgentStrings
.Where<UserAgentString>(p => p.DeviceID == 0 &&
!p.UserAgentString1.Contains("msie"));
//WORKS
userAgentStrings.ToList().ForEach(uas => ProcessUserAgentString(uas));
//WORKS
Array.ForEach(userAgentStrings.ToArray(), uas => ProcessUserAgentString(uas));
//Doesn't WORK
userAgentStrings.ForEach(uas => ProcessUserAgentString(uas));
Ответы
Ответ 1
Какое удивительное совпадение, я только что написал статью в блоге по этому самому вопросу. Это будет опубликовано 18 мая. Нет никаких технических причин, по которым мы (или вы!) Не могли этого сделать. Причины, по которым они не являются философскими. Смотрите мой блог на следующей неделе для моего аргумента.
Ответ 2
Совершенно можно написать метод расширения ForEach
для IEnumerable<T>
.
Я не уверен, почему он не включен как встроенный метод расширения:
- Возможно, потому что
ForEach
уже существовал на List<T>
и Array
до LINQ.
- Может быть, потому что достаточно просто использовать цикл
ForEach
для итерации последовательности.
- Возможно, потому, что не было функционально /LINQy.
- Может быть, потому что он не связан с цепью. (Легко сделать цепочку для версии
yield
каждого элемента после выполнения действия, но это поведение не особенно интуитивно понятно.)
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (source == null) throw new ArgumentNullException("source");
if (action == null) throw new ArgumentNullException("action");
foreach (T item in source)
{
action(item);
}
}