Есть ли итератор .Each() (или .ForEach()) в стандартной библиотеке .Net?

Возможный дубликат:
LINQ эквивалент foreach для IEnumerable <T>

Мне интересно, есть ли метод IEnumerable, например, следующий .Each() в библиотеке .Net

var intArray = new [] {1, 2, 3, 4};
intArrary.Each(Console.WriteLine);

Я знаю, что могу использовать цикл foreach или легко написать метод расширения следующим образом:

public static class EnumerableExtensions
{
    public static void Each<T>(this IEnumerable<T> enumberable, Action<T> action)
    {
        foreach (var item in enumberable)
        {
            action(item);
        }
    }
}

Но я надеюсь не создавать свой собственный метод, чтобы испортить код, если в библиотеке уже есть такой метод расширения. И что-то вроде .Each() (с несколькими перегрузками, которые могут принимать условия в качестве дополнительных параметров) в значительной степени необходимы программистам, и их уже должно быть. Правильно ли я?

Обновление

Разработчики Ruby могут распознать его как .each() итератор. И это то, что я надеюсь иметь на С#. Возможно, С# может иметь больше методов итератора, например, в Ruby.

Ответы

Ответ 1

Как говорили другие, на IEnumerable<T> нет встроенного. Команда Linq была против этого, как в этом сообщении Эрика Липперта:: http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

Существует статический метод на Array.ForEach, а List<T> - метод экземпляра. Есть также в PLINQ foreach как заявления, но имейте в виду, что они работают параллельно и могут привести к очень плохой производительности для чрезвычайно простых действий. Вот один из таких методов в PLINQ: http://msdn.microsoft.com/en-us/library/dd383744.aspx

И вот руководство по PLINQ в целом: http://msdn.microsoft.com/en-us/library/dd460688.aspx

Пока я не могу найти точную статью, если вы соскучились в секции ParrallelEnumerable, она дает предупреждения и советы о том, как повысить производительность использования parallelism в коде

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

public static void ForEach<T>(IEnumerable<T> enumerable,Action<T> action)
{
    foreach(var item in enumerable) action(item);
}

public static void ForEach<T>(IEnumerable<T> enumerable,Action<T,int> action)
{
    int index = 0;
    foreach(var item in enumerable) action(item,index++);
}

Я бы также включил проверку аргументов, поскольку это общедоступные методы.

Ответ 2

Да, есть.

someList.ForEach(x => Console.WriteLine(x));

Или с массивом:

Array.ForEach(someArray, x => Console.WriteLine(x));

Обратите внимание, что в этом последнем примере вам нужно вызвать статический метод в классе Array

EDIT: пространства имен: System.Collections.Generic для метода List и System для метода Array

Ответ 3

Существует метод ForEach в System.Collections.List <T> , но не на IEnumerable. Обратите внимание, что это также не часть LINQ (она уже была в .NET 2.0).

На первый взгляд вы ожидаете, что это будет часть LINQ, так как это будет расширение для нормальной функции списка. Однако LINQ больше связан с группировкой, фильтрацией и преобразованием данных. Если вы внимательно присмотритесь, большинство (если не все, я не Джон Скит, я не знаю этого наизусть!) Методы LINQ возвращают некоторый тип IEnumerable.

Однако вы можете взглянуть на MoreLinq. Это проект с открытым исходным кодом, который добавляет некоторые ключевые функции в существующий LINQ to Objects, один из которых - это метод ForEach, который вы хотите (работает в любом IEnumerable в этом случае, поэтому он также будет работать и с вашим массивом).

Ответ 4

Нет, к сожалению, нет. (Я думаю, этот вопрос обсуждался ранее, но я не могу найти его в настоящее время.)

Из-за какой-то странной случайности история ForEach оказалась в List<T> вместо IEnumerable<T>, где это будет иметь больше смысла, и из-за обратной совместимости это никогда не может быть исправлено.

С тех пор, как существовали методы расширения, добавление метода расширения ForEach(this IEnumerable<T>, ...) было запрошено снова и снова, но оно обычно отклоняется, потому что это приведет к запутанному поведению: поскольку методы экземпляра всегда выбираются перед методами расширения, это будет означать, что все IEnumerable обрабатываются одинаково, кроме List, и они не допускают таких несоответствий в BCL.

В результате почти каждый проект .NET на планете теперь начинается именно с кода, описанного выше:

namespace IEnumerableExtensions
{
    public static class IEnumerableExtensions
    {
        public static void ForEach<T>(this IEnumerable<T> xs, Action<T> f)
        {
            foreach (var x in xs) f(x);
        }
    }
}

Ответ 5

Только List<T> предоставляет ForEach метод - для всех остальных типов вам придется перевернуть свой собственный метод расширения.

Ответ 6

это зависит от версии рамки

.net 3.5 и 4.0 имеют метод ForEach