LINQ equivalent of foreach for IEnumerable

后端 未结 22 2248
夕颜
夕颜 2020-11-21 22:54

I\'d like to do the equivalent of the following in LINQ, but I can\'t figure out how:

IEnumerable items = GetItems();
items.ForEach(i => i.DoS         


        
相关标签:
22条回答
  • 2020-11-21 23:20

    The purpose of ForEach is to cause side effects. IEnumerable is for lazy enumeration of a set.

    This conceptual difference is quite visible when you consider it.

    SomeEnumerable.ForEach(item=>DataStore.Synchronize(item));

    This wont execute until you do a "count" or a "ToList()" or something on it. It clearly is not what is expressed.

    You should use the IEnumerable extensions for setting up chains of iteration, definining content by their respective sources and conditions. Expression Trees are powerful and efficient, but you should learn to appreciate their nature. And not just for programming around them to save a few characters overriding lazy evaluation.

    0 讨论(0)
  • 2020-11-21 23:21

    As numerous answers already point out, you can easily add such an extension method yourself. However, if you don't want to do that, although I'm not aware of anything like this in the BCL, there's still an option in the System namespace, if you already have a reference to Reactive Extension (and if you don't, you should have):

    using System.Reactive.Linq;
    
    items.ToObservable().Subscribe(i => i.DoStuff());
    

    Although the method names are a bit different, the end result is exactly what you're looking for.

    0 讨论(0)
  • 2020-11-21 23:21

    To stay fluent one can use such a trick:

    GetItems()
        .Select(i => new Action(i.DoStuf)))
        .Aggregate((a, b) => a + b)
        .Invoke();
    
    0 讨论(0)
  • 2020-11-21 23:23

    Yet another ForEach Example

    public static IList<AddressEntry> MapToDomain(IList<AddressModel> addresses)
    {
        var workingAddresses = new List<AddressEntry>();
    
        addresses.Select(a => a).ToList().ForEach(a => workingAddresses.Add(AddressModelMapper.MapToDomain(a)));
    
        return workingAddresses;
    }
    
    0 讨论(0)
  • 2020-11-21 23:24

    MoreLinq has IEnumerable<T>.ForEach and a ton of other useful extensions. It's probably not worth taking the dependency just for ForEach, but there's a lot of useful stuff in there.

    https://www.nuget.org/packages/morelinq/

    https://github.com/morelinq/MoreLINQ

    0 讨论(0)
  • 2020-11-21 23:26

    If you want to act as the enumeration rolls you should yield each item.

    public static class EnumerableExtensions
    {
        public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
        {
            foreach (var item in enumeration)
            {
                action(item);
                yield return item;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题