For what it's worth, a Dictionary is (conceptually) a hash table.
If you meant "why do we use the Dictionary<TKey, TValue>
class instead of the Hashtable
class?", then it's an easy answer: Dictionary<TKey, TValue>
is a generic type, Hashtable
is not. That means you get type safety with Dictionary<TKey, TValue>
, because you can't insert any random object into it, and you don't have to cast the values you take out.
Interestingly, the Dictionary<TKey, TValue>
implementation in the .NET Framework is based on the Hashtable
, as you can tell from this comment in its source code:
The generic Dictionary was copied from Hashtable's source
Source
Yes, it is important if your item will be used as a key in a dictionary, or HashSet<T>
, etc - since this is used (in the absence of a custom IEqualityComparer<T>
) to group items into buckets. If the hash-code for two items does not match, they may never be considered equal (Equals will simply never be called).
The GetHashCode() method should reflect the Equals
logic; the rules are:
- if two things are equal (
Equals(...) == true
) then they must return the same value for GetHashCode()
- if the
GetHashCode()
is equal, it is not necessary for them to be the same; this is a collision, and Equals
will be called to see if it is a real equality or not.
In this case, it looks like "return FooId;
" is a suitable GetHashCode()
implementation. If you are testing multiple properties, it is common to combine them using code like below, to reduce diagonal collisions (i.e. so that new Foo(3,5)
has a different hash-code to new Foo(5,3)
):
unchecked // only needed if you're compiling with arithmetic checks enabled
{ // (the default compiler behaviour is *disabled*, so most folks won't need this)
int hash = 13;
hash = (hash * 7) + field1.GetHashCode();
hash = (hash * 7) + field2.GetHashCode();
...
return hash;
}
Oh - for convenience, you might also consider providing ==
and !=
operators when overriding Equals
and GetHashCode
.
A demonstration of what happens when you get this wrong is here.
Best Answer
There is already a
foreach
statement included in the language that does the job most of the time.I'd hate to see the following:
Instead of:
The latter is clearer and easier to read in most situations, although maybe a bit longer to type.
However, I must admit I changed my stance on that issue; a
ForEach()
extension method would indeed be useful in some situations.Here are the major differences between the statement and the method:
ForEach()
is at compile time (Big Plus!)Those are all great points made by many people here and I can see why people are missing the function. I wouldn't mind Microsoft adding a standard ForEach method in the next framework iteration.