Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ's ForEach on HashSet?

Tags:

c#

linq

hashset

I am curious as to what restrictions necessitated the design decision to not have HashSet's be able to use LINQ's ForEach query.

What's really going on differently behind the scenes for these two implementations:

var myHashSet = new HashSet<T>;
foreach( var item in myHashSet ) { do.Stuff(); }

vs

var myHashSet = new HashSet<T>;
myHashSet.ForEach( item => do.Stuff(); }

I'm (pretty) sure that this is just because HashSet does not implement IEnumerable -- but what is a normal ForEach loop doing differently that makes it more supported by a HashSet?

Thanks

like image 564
Sean Anderson Avatar asked Nov 02 '11 16:11

Sean Anderson


3 Answers

LINQ doesn't have ForEach. Only the List<T> class has a ForEach method.

It's also important to note that HashSet does implement IEnumerable<T>.

Remember, LINQ stands for Language INtegrated Query. It is meant to query collections of data. ForEach has nothing to do with querying. It simply loops over the data. Therefore it really doesn't belong in LINQ.

like image 81
Justin Niessner Avatar answered Oct 04 '22 22:10

Justin Niessner


LINQ is meant to query data, I'm guessing it avoided ForEach() because there's a chance it could mutate data that would affect the way the data could be queried (i.e. if you changed a field that affected the hash code or equality).

You may be confused with the fact that List<T> has a ForEach()?

It's easy enough to write one, of course, but it should be used with caution because of those aforementioned concerns...

public static class EnumerableExtensions
{
    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(var item in source)
        {
            action(item);
        }
    }
}
like image 32
James Michael Hare Avatar answered Oct 04 '22 22:10

James Michael Hare


var myHashSet = new HashSet<T>;
myHashSet.ToList().ForEach( x => x.Stuff() );
like image 33
themadmax Avatar answered Oct 04 '22 23:10

themadmax