Reputation: 29291
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
Upvotes: 6
Views: 11030
Reputation: 2404
var myHashSet = new HashSet<T>;
myHashSet.ToList().ForEach( x => x.Stuff() );
Upvotes: 3
Reputation: 245419
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.
Upvotes: 11
Reputation: 38397
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);
}
}
}
Upvotes: 6
Reputation: 149
The first use the method GetEnumerator of HashSet The second the method ForEach
Maybe the second use GetEnumerator behind the scene but I'm not sure.
Upvotes: -1