Force Dictionary to use Identity versus Equality

  • Thread starter Thread starter jehugaleahsa
  • Start date Start date
J

jehugaleahsa

Hello:

Is there a way to force a Dictionary to determine equivilence by
memory location?

I have a generic class where I don't want to treat equal items as
identical items. Only when two references point to the same instance
do I want to treat them as the same dictionary key.

Any help?

Thanks,
Travis
 
I created an IdentityComparer like this:

public class IdentityComparer : IEqualityComparer<TDataRecord>
{
public bool Equals(TDataRecord x, TDataRecord y)
{
return Object.ReferenceEquals(x, y);
}

public int GetHashCode(TDataRecord obj)
{
return obj.GetHashCode();
}
}

I pass this to the constructor of the Dictionary. Is there a way to
improve the GetHashCode, however?
 
Hello:

Is there a way to force a Dictionary to determine equivilence by
memory location?

I have a generic class where I don't want to treat equal items as
identical items. Only when two references point to the same instance
do I want to treat them as the same dictionary key.

Any help?

Dictionary accepts an EqualityComparer delegate in the constructor, use
object.ReferenceEquals as the EqualityComparer.
 
Thanks. Any ideas about improving the GetHashCode?

I'm assuming there isn't anything I can do about the GetHashCode. I
can't use memory addresses since they are volitile because of the
memory management.

Thanks again,
Travis
 
Thanks. Any ideas about improving the GetHashCode?

I'm assuming there isn't anything I can do about the GetHashCode. I
can't use memory addresses since they are volitile because of the
memory management.

Sorry, I don't know of any particular solution for that. But hash code
collisions should be pretty minimal unless the number of objects which are
equal-in-value-but-not-reference is a lot higher than you suggested.
 
Thanks. Any ideas about improving the GetHashCode?

I'm assuming there isn't anything I can do about the GetHashCode. I
can't use memory addresses since they are volitile because of the
memory management.

There isn't anything that can be done in pure C#. However, it is
possible in IL to make non-virtual method calls even for virtual
methods, explicitly specifying the type that should provide the
implementation that is called. In your case, what you need is to make
a non-virtual call to Object.GetHashCode() on your objects - that
would be the default implementation that provides identity-based hash.
So, you take the C# code written along these lines:

using System;
using System.Collections.Generic;

public class IdentityComparer<T> : IEqualityComparer<T>
where T : class
{
public bool Equals(T x, T y)
{
return x == y;
}

public int GetHashCode(T x)
{
return x.GetHashCode();
}
}

Compile it, then ildasm it. In the resulting .il file, find this
instruction:

callvirt instance int32 [mscorlib]System.Object::GetHashCode()

replace "callvirt" with "call", and use ilasm to recompile the
assembly. Now you've got your identity comparer with proper
GetHashCode().
 

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

Similar Threads

Fill Dictionary in a Fluent Way 4
Extending Dictionary 2
Check identity dictionary 2
Dictionary of classes 3
Dictionary 3
Create List or Dictionary 3
learning to code - dictionary question 8
Dictionary 1

Back
Top