Object identity for Hashtables

  • Thread starter Clemens Hoffmann
  • Start date
C

Clemens Hoffmann

Hello,

i have a nasty problem with object identity in
hash tables. I try to use different objects as keys.
It failed bacause i cannot identify object propperly.
Different objects with the same contents have
the same hash code.

DateTime date1 = new DateTime(2001,11,22);
DateTime date2 = new DateTime(2001,11,22);

date1 und date2 have the same hash code. I checked
google and found a thread where a posible solution
for object identity was discussed.

(http://groups.google.de/groups?hl=de&lr=&ie=UTF-8&oe=UTF-8&threadm=#xZ2Zw
7pCHA.504%40TK2MSFTNGP12&rnum=1&prev=/groups%3Fhl%3Dde%26ie%3DUTF-8%26oe%3DU
TF-8%26q%3D%2522RuntimeHelpers.GetHashCode%2522%26sa%3DN%26tab%3Dwg%26meta%3
D)

Unfortenately it just don't work as the method Object.GetHashCode()
does not answer an object identity but a stubid sequence number.

System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(date1) -> 1
System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(date2) -> 2
System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(date1) -> 3

What i need is a method that answers an id that uniquely identifies an
object.
Send to two instances of a class that have the same value must answer
different values. Send two times to the same object must answer the same
value. Is there such a method in .NET?

I added a small sample that shows the problem.

----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Runtime.CompilerServices;

namespace HashtableTest
{
public class IdentityHashcodeProvider : IHashCodeProvider
{
public int GetHashCode(Object obj)
{
return RuntimeHelpers.GetHashCode(obj);
}
}

public class IdentityComparer : IComparer
{
public int Compare(Object obj1, Object obj2)
{
if (Object.ReferenceEquals(obj1, obj2)) return 0;
else return 1;
}
}

class Class1
{
[STAThread]
static void Main(string[] args)
{
DateTime date1 = new DateTime(2001,11,22);
DateTime date2 = new DateTime(2001,11,22);

Console.WriteLine("HashCode for Date 1 : {0}",
RuntimeHelpers.GetHashCode(date1));
Console.WriteLine("HashCode for Date 2 : {0}",
RuntimeHelpers.GetHashCode(date2));
Console.WriteLine("HashCode for Date 1 : {0}",
RuntimeHelpers.GetHashCode(date1));

IdentityHashcodeProvider provider = new
dentityHashcodeProvider();
IdentityComparer comparer = new IdentityComparer();
Hashtable table = new Hashtable(10, provider, comparer);

table.Add(date1, date1.ToString());
if (table.ContainsKey(date2)) Console.WriteLine("No No");
else Console.WriteLine("Ok");

table.Add(date2, date2.ToString());
if (table.ContainsKey(date2)) Console.WriteLine("Ok");
else Console.WriteLine("No No");
}
}
}

----------------------------------------------------------------------------

The other solution discussed there using reflection generates the same
result.
Relacing the statement return RuntimeHelpers.GetHashCode(obj);
with the statments below does not change anything.

System.Reflection.MethodInfo mm;
Type tt = typeof(Object);
mm = tt.GetMethod("GetHashCode");
return (int) mm.Invoke(obj, null);

greetings

Clemens Hoffmann
 
J

Jon Skeet

Clemens Hoffmann said:
i have a nasty problem with object identity in
hash tables. I try to use different objects as keys.
It failed bacause i cannot identify object propperly.
Different objects with the same contents have
the same hash code.

DateTime date1 = new DateTime(2001,11,22);
DateTime date2 = new DateTime(2001,11,22);

First you need to realise that DateTime is a structure, not a class, so
those are both value type variables. They'll end up being boxed when
you put them in a hashtable. That means if you were using object
identity you would *never* be able to get the value out again in the
normal way, as you'd end up with a different box each time. This is
probably why RuntimeHelpers.GetHashCode was returning different values,
too.
date1 und date2 have the same hash code.

They not only have the same hash code, they are also equal to each
other. The two variables have *exactly* the same value. This is
slightly different from the case where you have two reference type
values which refer to different but equal objects, e.g.

String s1 = "hello";
String s2 = String.Concat ("he", "llo");
What i need is a method that answers an id that uniquely identifies an
object. Send to two instances of a class that have the same value must answer
different values.

Are you interested in instances of classes, or structure values? How
clear are you on the difference between reference types and value
types? It'll be very important when it comes to implementing what you
want to do.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top