From: Tony Johansson on
Hello!

First some background information before I ask the question.The text is just
copied from a book that I'm reading
The .Net Framework doesn't always understand equality as we do, however. For
example, imagine you created class Fish
that holds the name of the fish like below.

public class Fish
{
string name;

public Fish(string theName)
{
name = theName;
}
}

Now if we create two instances of the Fish class with the same name, the
Hashtable treats them as different objects, as shown in the following code
example.

Hashtable duplicates = new Hashtable();
Fish key1 = new Fish("Herring");
Fish key2 = new Fish("Herring");
duplicates[key1] = "Hello";
duplicates[key2] = "Hello";
Console.WriteLine(duplicates.Count); // give 2

The reason we have two items in the collection is because the Object class's
implementation of GetHashCode creates a hash that is likely to be unique for
each instance of a class. I can override the GetHashCode in the Fish class
to try and let the Hashtable known they are equal.

Here is the code that override the GetHashCode in class Fish
public override int GetHashCode()
{
return name.GetHashCode();
}

If I return the hash of the fish's name, the two instances of the fish will
have the same hash code.
But is that enough for the Hashtable to determine they are identical
objects. Unfortunately, no. If the Hashtable find two objects with the same
hash, it calls their Equals method to see whether the two objects are in
fact equal. Again, the default implementation of Objects.Equals will return
false if the two objects are two different instances of the same class. So
we need to also add an override of the Equals method to our Fish class.

Now to my question: I mean that if the hash code is the same as in my
example then the object are equal so I don't understand why the framework
must call the equals.

Can somebody give me an example when you have the same hashcode but the
object is not equal.

//Tony



From: Stefan Hoffmann on
hi Tony,

On 05.06.2010 13:55, Tony Johansson wrote:
> Now to my question: I mean that if the hash code is the same as in my
> example then the object are equal so I don't understand why the framework
> must call the equals.
This is not correct, see

http://en.wikipedia.org/wiki/Hash_code

Different, not equal objects may produce or return the same hash code.

http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx


mfG
--> stefan <--
From: Willem van Rumpt on
On 5-6-2010 13:55, Tony Johansson wrote:
>
> Now to my question: I mean that if the hash code is the same as in my
> example then the object are equal so I don't understand why the framework
> must call the equals.
>
> Can somebody give me an example when you have the same hashcode but the
> object is not equal.
>
> //Tony
>

Becasue, in general, a hash is not unique (unless you want a perfect
hash). Ideally, it should be as unique as possible, but it doesn't have
to be.

Hashes are a characteristic, and in a hashtable, everything with the
same characteristic goes into the same bucket. So when more than one
item is a the bucket, there has to be a way to find the correct item.
Equals solves that problem.

Think of "wears glasses" as a hashcode.
All your friends wearing glasses hash to "wears glasses", but they are
most definitely not equal to each other.

--
Willem van Rumpt
From: Arne Vajhøj on
On 05-06-2010 07:55, Tony Johansson wrote:
> First some background information before I ask the question.The text is just
> copied from a book that I'm reading
> The .Net Framework doesn't always understand equality as we do, however. For
> example, imagine you created class Fish
> that holds the name of the fish like below.
>
> public class Fish
> {
> string name;
>
> public Fish(string theName)
> {
> name = theName;
> }
> }
>
> Now if we create two instances of the Fish class with the same name, the
> Hashtable treats them as different objects, as shown in the following code
> example.
>
> Hashtable duplicates = new Hashtable();
> Fish key1 = new Fish("Herring");
> Fish key2 = new Fish("Herring");
> duplicates[key1] = "Hello";
> duplicates[key2] = "Hello";
> Console.WriteLine(duplicates.Count); // give 2
>
> The reason we have two items in the collection is because the Object class's
> implementation of GetHashCode creates a hash that is likely to be unique for
> each instance of a class. I can override the GetHashCode in the Fish class
> to try and let the Hashtable known they are equal.
>
> Here is the code that override the GetHashCode in class Fish
> public override int GetHashCode()
> {
> return name.GetHashCode();
> }
>
> If I return the hash of the fish's name, the two instances of the fish will
> have the same hash code.
> But is that enough for the Hashtable to determine they are identical
> objects. Unfortunately, no. If the Hashtable find two objects with the same
> hash, it calls their Equals method to see whether the two objects are in
> fact equal. Again, the default implementation of Objects.Equals will return
> false if the two objects are two different instances of the same class. So
> we need to also add an override of the Equals method to our Fish class.
>
> Now to my question: I mean that if the hash code is the same as in my
> example then the object are equal so I don't understand why the framework
> must call the equals.
>
> Can somebody give me an example when you have the same hashcode but the
> object is not equal.

The logic is:
- If Equals return true it is the "same" object
- GetHashCode returns an int for all objects, if Equals return true then
GetHashCode must return the same value, but returning "good" values
from GetHashCode is only for good performance

public override int GetHashCode()
{
return 1;
}

is valid implementation.

But it will make Hashtable lookup O(n) instead of O(1), so
it would be very bad for performance.

You want a GetHashCode that returns many different values.

Arne



From: Tony Johansson on

"Arne Vajh�j" <arne(a)vajhoej.dk> skrev i meddelandet
news:4c0a54ce$0$284$14726298(a)news.sunsite.dk...
> On 05-06-2010 07:55, Tony Johansson wrote:
>> First some background information before I ask the question.The text is
>> just
>> copied from a book that I'm reading
>> The .Net Framework doesn't always understand equality as we do, however.
>> For
>> example, imagine you created class Fish
>> that holds the name of the fish like below.
>>
>> public class Fish
>> {
>> string name;
>>
>> public Fish(string theName)
>> {
>> name = theName;
>> }
>> }
>>
>> Now if we create two instances of the Fish class with the same name, the
>> Hashtable treats them as different objects, as shown in the following
>> code
>> example.
>>
>> Hashtable duplicates = new Hashtable();
>> Fish key1 = new Fish("Herring");
>> Fish key2 = new Fish("Herring");
>> duplicates[key1] = "Hello";
>> duplicates[key2] = "Hello";
>> Console.WriteLine(duplicates.Count); // give 2
>>
>> The reason we have two items in the collection is because the Object
>> class's
>> implementation of GetHashCode creates a hash that is likely to be unique
>> for
>> each instance of a class. I can override the GetHashCode in the Fish
>> class
>> to try and let the Hashtable known they are equal.
>>
>> Here is the code that override the GetHashCode in class Fish
>> public override int GetHashCode()
>> {
>> return name.GetHashCode();
>> }
>>
>> If I return the hash of the fish's name, the two instances of the fish
>> will
>> have the same hash code.
>> But is that enough for the Hashtable to determine they are identical
>> objects. Unfortunately, no. If the Hashtable find two objects with the
>> same
>> hash, it calls their Equals method to see whether the two objects are in
>> fact equal. Again, the default implementation of Objects.Equals will
>> return
>> false if the two objects are two different instances of the same class.
>> So
>> we need to also add an override of the Equals method to our Fish class.
>>
>> Now to my question: I mean that if the hash code is the same as in my
>> example then the object are equal so I don't understand why the framework
>> must call the equals.
>>
>> Can somebody give me an example when you have the same hashcode but the
>> object is not equal.
>
> The logic is:
> - If Equals return true it is the "same" object
> - GetHashCode returns an int for all objects, if Equals return true then
> GetHashCode must return the same value, but returning "good" values
> from GetHashCode is only for good performance
>
> public override int GetHashCode()
> {
> return 1;
> }
>
> is valid implementation.
>
> But it will make Hashtable lookup O(n) instead of O(1), so
> it would be very bad for performance.
>
> You want a GetHashCode that returns many different values.
>
> Arne
>

Hi!

I still mean that if the hash code is the same then you must have identical
keys so I don't see any point why the
framework must call the equals. ?
Can somebody exaplin that ?

//Tony



//Tony