views:

268

answers:

3

Hi,

I have a class A that implements IEquatable<>, using its fields (say, A.b and A.c) for implementing/overriding Equals() and overriding GetHashCode(), and everything works fine, 99% of the time. Class A is part of a hierarchy (class B, C) that all inherit from interface D; they can all be stored together in a dictionary Dictionary, thus it's convenient when they all carry their own default Equals()/GetHashCode().

However, while constructing A I sometime need to do some work to get the values for A.b and A.c; while that's happening, I want to store a reference to the instance that's being built. In that case, I don't want to use the default Equals()/GetHashCode() overrides provided by A. Thus, I was thinking of implementing a ReferenceEqualityComparer, that's meant to force the use of Object's Equals()/GetHashCode():

    private class ReferenceEqualityComparer<T> : IEqualityComparer<T>
    {
        #region IEqualityComparer<T> Members
        public bool Equals(T x, T y)
        {
            return System.Object.ReferenceEquals(x, y);
        }

        public int GetHashCode(T obj)
        {
            // what goes here? I want to do something like System.Object.GetHashCode(obj);
        }
        #endregion
    }

The question is, since A overrides Object.GetHashCode(), how can I (outside of A) call Object.GetHashCode() for an instance of A?

One way of course would be for A to not implement IEquatable<> and always supply an IEqualityComparer<> to any dictionary that I create, but I'm hoping for a different answer.

Thanks

A: 

Wouldn't this work if you added the type constraint where T : object to your class? I don't have a compiler on this computer and I have to run, but good luck.

public int GetHashCode(T obj)  
    {  
        object obj = T;  
        return obj.GetHashCode();
    }
Brett Widmeier
Guess not. Sorry.
Brett Widmeier
A: 

Call the CLR's base implementation via interop: http://stackoverflow.com/questions/720177/default-implementation-for-object-gethashcode

piers7
The link is interesting for academic purposes, but you should really use `RuntimeHelpers.GetHashCode()` instead.
280Z28
True, didn't know about that one. It does just call exactly the same underlying interop method, so there's no functional difference (but yeah: you should use the published API in case it changes etc...)
piers7
+2  A: 

The natural match for object.ReferenceEquals is RuntimeHelpers.GetHashCode.

See the answer to this question for full details and an implementation of ObjectReferenceEqualityComparer<T>: Built-in IEqualityComparer<T> that uses ReferenceEquals

280Z28
I like it -- thanks!
Jimmy