1

After a couple hours of research (on MSDN websites and so on) I didn't manage to find out why the generic Dictionary<TKey, TValue> does not provide a ForEach() method like List<T> does. Could someone please give me an explanation? (I know that it's not hard to implement it as an extension method, a great example can be seen here, I just was wondering whether there might be a particular reason why it's not provided by the .NET libraries in the first place.)

Thanks in advance.

mindthegap
  • 323
  • 2
  • 7
  • 19
  • The answer is there in the question you referenced: **A dictionary only has one value per key, so there is no need to foreach**. – Jeremy Thompson Sep 15 '17 at 00:09
  • 1
    Yes, but he may want to iterate through all of the KVPs in the dictionary. – Kevin Hirst Sep 15 '17 at 00:12
  • @Jeremy Does `IDictionary<,>` not implement `IEmumerable>`? If one is needless, surely the other is as well. Java's `Map<,>` has a `forEachEntry` method. Perhaps that is what OP was inquiring about. – Mike Strobel Sep 15 '17 at 00:13
  • Agree, that's what I meant - would have liked to iterate over the entries like this: `d.ForEach(p => { Console.WriteLine(p.Key + ' ' + p.Value); });`. – mindthegap Sep 15 '17 at 00:28
  • `I just was wondering whether there might be a particular reason why it's not provided by the .NET libraries in the first place` Presumably because Microsoft didn't think the effort required to build, test, document and support it was warranted. _Especially since, with extension methods, you could build it yourself in < 5 minutes._ – mjwills Sep 15 '17 at 00:38
  • Possible duplicate of [Why there is no ForEach extension method on IEnumerable?](https://stackoverflow.com/questions/101265/why-there-is-no-foreach-extension-method-on-ienumerable) – Discoverer98 Sep 15 '17 at 00:40
  • usually you wouldn't iterate over dictionary, it doesn't have iteration semantics, of course you can still iterate over items but order of adding items is not preserved either. – M.kazem Akhgary Sep 15 '17 at 00:49
  • What do you mean by _not having iteration semantics_? How can one determine this? Does this depend on the implemented interfaces (just checked on MSDN, it implements all the interfaces, or similars, that `List` does, i.e.)? Being able to iterate over a dictionary in a `foreach` loop doesn't contradict this? Thank you for your time. Thanks for the potential duplicate, as well, will check the answers soon. – mindthegap Sep 15 '17 at 01:02
  • 2
    List.ForEach has a very strong implicit guarantee: the order in which the elements are exposed is highly deterministic. Adding or removing an item does not fundamentally change that. Dictionary cannot provide any such guarantee, it is not an ordered collection. Especially bad since it easily *looks* ordered, you do tend to get back the items in the order in which they were added. But that can randomly change when it decides to re-organize the buckets. – Hans Passant Sep 15 '17 at 03:46

1 Answers1

5

Because it's questionable why List<T> has it in the first place. No need to repeat the same mistake everywhere. Eric Lippert gives two reason as to why in his blog post :

The first reason is that doing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects. (...)

The second reason is that doing so adds zero new representational power to the language. Doing this lets you rewrite this perfectly clear code:

foreach(Foo foo in foos){ statement involving foo; }

into this code:

foos.ForEach((Foo foo)=>{ statement involving foo; });

which uses almost exactly the same characters in slightly different order. And yet the second version is harder to understand, harder to debug, and introduces closure semantics, thereby potentially changing object lifetimes in subtle ways. (...)

Asik
  • 21,506
  • 6
  • 72
  • 131