Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C#

Looking up items in HashTable/Dictionary objects that have multiple keys

Rate me:
Please Sign up or sign in to vote.
4.20/5 (8 votes)
1 May 2008CPOL4 min read 87.6K   585   23  
Dictionary objects take a single key as a look up key. This class simplifies using a Dictionary when you have multiple keys, such as two strings and an int, etc.
using System;
using System.Collections.Generic;
using System.Text;

namespace Utility
{
    /// <summary>
    /// Defines a common set of operations and functionality for creating concrete key classes which allow us to lookup items in a collection
    /// using one or more of the properties in that collection.
    /// </summary>
    public struct ClassKeyStruct
    {
        /// <summary>
        /// Init with specific collection item
        /// </summary>
        /// <param name="CollectionItem"></param>
        public ClassKeyStruct(object[] KeyValues)
        {
            this.KeyValues = KeyValues;
        }
        private object[] KeyValues;

        /// <summary>
        /// Compare based on hash code
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj is ClassKeyStruct)
            {
                return ((ClassKeyStruct)obj).GetHashCode() == this.GetHashCode();
            }
            else
                return false; //definitely not equal
        }

        public static bool operator ==(ClassKeyStruct p1, ClassKeyStruct p2)
        {
            //if both null, then equal
            if ((object)p1 == null && (object)p2 == null) return true;

            //if one or other null, then not since above we guaranteed if here one is not null
            if ((object)p1 == null || (object)p2 == null) return false;

            //compare on fields
            return (p1.Equals(p2));
        }

        public static bool operator !=(ClassKeyStruct p1, ClassKeyStruct p2)
        {
            return !(p1 == p2);
        }

        /// <summary>
        /// Implement hash code function to specify which columns will be used for the key without using reflection which may be a bit slow.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            //use co-prime numbers to salt the hashcode so same values in different order will not return as equal - see TestClassKeyXOROrderProblem to reproduce problem 
            //http://www.msnewsgroups.net/group/microsoft.public.dotnet.languages.csharp/topic36405.aspx
            //http://directxinfo.blogspot.com/2007/06/gethashcode-in-net.html
            int FinalHashCode = 17; //first co-prime number
            int OtherCoPrimeNumber = 37; //other co-prime number - ask me if I know what co-prime means, go ahead, ask me.

            //get total hashcode to return
            if(KeyValues != null)
                foreach (object keyValue in KeyValues)
                {
                    //can't get hash code if null
                    if (keyValue != null)
                    {
                        FinalHashCode = FinalHashCode * OtherCoPrimeNumber + keyValue.GetHashCode();
                    }
                }

            return FinalHashCode;
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I've been a software developer since 1996 and have enjoyed C# since 2003. I have a Bachelor's degree in Computer Science and for some reason, a Master's degree in Business Administration. I currently do software development contracting/consulting.

Comments and Discussions