Forum guidelines
AuthorQuestion
Uses of GetHashCode and Equals
Posted on: 25 Nov 2012

Hi,

I am trying to understand a piece of code which basically uses GetHashCode() and Equals(). I googled it but still can't find any good artical to understand. MsDN has something but cud'nt understand.

The below metioned code has been used in my app class library. I have taken it out and put it in console app and used some constant value just to make it compilable.

Can someone explain me the use of NameValuePair class from below code snippet. More specifically the use of GetHashCode and Equals (If posible if you can put line by line comment for each line for method GetHashCode and Equals stating why we have written it, wud be great).


Code:


 class Program
    {
        private static readonly IDictionary<NameValuePair, string> myNameValueAssetMappings =
            new Dictionary<NameValuePair, string>();

        static void Main(string[] args)
        {
            // some code
           
            var pair = ConstructNameValuePair("someName", "SomeValue");
            if (pair != null)
            {
                myNameValueAssetMappings[pair] = "20000"; // this value will be coming from somewhere else
            }

            Console.ReadKey();
        }

        private static NameValuePair ConstructNameValuePair(string name, string value)
        {
           // some code

            return new NameValuePair(name, value);
        }  

        #region NameValuePair

        private sealed class NameValuePair : Tuple<string, string>
        {
           
            internal NameValuePair(string name, string value) :
                base(name, value)
            {
                // left empty
            }

            /// <see cref="object.GetHashCode"/>
            public override int GetHashCode()
            {
                return Item1.GetHashCode() + 5 * Item2.GetHashCode();
            }

            public override bool Equals(object obj)
            {
                if (obj == this)
                {
                    return true;
                }
                var otherPair = obj as NameValuePair;
                if (otherPair == null)
                {
                    return false;
                }
                return otherPair.Item1 == Item1 &&
                       otherPair.Item2 == Item2;
            }
        }

        #endregion
    }

Thanks a lot for taking time to read this.

your help will be highly appriciated.

Best Regards.

v


AuthorReply
Vulpes
  • 0
  • 0
accepted
Re: Uses of GetHashCode and Equals
Posted on: 25 Nov 2012   Accepted Answer
The NameValuePair class is extending the Tuple<string, string> class. The latter represents an ordered pair of strings and has two properties, Item1 and Item2, which return the value of these strings.

A NameValuePair object is created by passing name and value strings to the constructor which are in turn passed to Tuple<string, string>'s constructor using the base keyword.

The writer of the class has decided to override the Equals method for the NameValuePair class so that two NameValuePair objects will be considered equal if either they are the same object or their names and values are both equal. The Tuple class does in fact override the Equals method in a similar fashion. The explanation of this method's code is as follows:

public override bool Equals(object obj)
{
    if (obj == this) // if obj is the same as the current object
    {
       return true; // it's definitely equal so return true
    }
    
    // check that obj is in fact a NameValuePair by attempting to cast it to that type
    var otherPair = obj as NameValuePair;
    if (otherPair == null) // if it isn't a NameValuePair
    {
       return false; // it's definitely not equal to the current object so return false
    }
                
    // Otherwise only return true if the corresponding names and values are equal.
    // For the current object these are represented by the inherited properties
    // Item1 and Item2
    return otherPair.Item1 == Item1 && otherPair.Item2 == Item2;
}

Now, when you override the Equals method, you should also override the GetHashCode method as well because this is used by hashtables, dictionaries and the like to identify an object during equality testing.

This is done here by multiplying the hashcode of the value by 5 and adding it to the hashcode of the name:

    public override int GetHashCode()
    {
       return Item1.GetHashCode() + 5 * Item2.GetHashCode();
    }

I don't know why this particular formula was used unless it's the formula used in the Tuple class itself or the writer considered that it should produce distinct values for the NameValuePairs that were likely to arise in practice.

SPONSORED BY

Custom Software Development
MCN is your source for developing solutions involving websites, mobile apps, cloud-computing, databases, BI, back-end services and processes and client-server applications.