How are HashCodes generates for classes vs. structs?

This is a discussion on How are HashCodes generates for classes vs. structs? within the C# Programming forums, part of the General Programming Boards category; I was trying to figure out a way to use a Dictionary to distinguish between unique combinations of pairs and ...

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    71

    How are HashCodes generates for classes vs. structs?

    I was trying to figure out a way to use a Dictionary to distinguish between unique combinations of pairs and accidentally realized that hashcodes for classes are generated differently than hashcodes for structs.

    Consider this code:

    Code:
            class C
             {
                 public string a { set; get; }
                 public string b { set; get; }
             }
    
            struct S
            {
                public string a { set; get; }
                public string b { set; get; }
            }
    
    
                Console.WriteLine(new C{ a = "ab", b = "cd" }.GetHashCode());
                Console.WriteLine(new C{ a = "ab", b = "cd" }.GetHashCode());
    
                Console.WriteLine(new S{ a = "ab", b = "cd" }.GetHashCode());
                Console.WriteLine(new S{ a = "ab", b = "cd" }.GetHashCode());
    if you run code similar to the one above, you'll notice that the two instances of the struct have the same hashcode, but the two instances of the class have a different hashcode.

    Can someone tell me how the hashcode is generated and why two instances of the same struct with the same properties have the same hashcode but the same is not true for two instances of the same class with the same properties?

  2. #2
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,139
    The short explanation is that it should be overridden anyway and it doesn't matter what "GetHashCode" returns as default. The long explanation is here.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  3. #3
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    Isn't that nice. I was looking into this as well and found that the method is essentially useless out of the box. It would have been nice if MS did actually have a hash algo under the hood that you could use without having to override and write your own.

  4. #4
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,272
    The hash code of an object is (conceptually) based on the object handle, which means distinct objects have (or at least, can have) distinct hash codes, regardless of whether their data content is equal.

    This is usually what you want, if you are using objects as keys in a Dictionary. If you want the hash code to be based on specific fields of the object, you'd need to implement it yourself anyway.

    Another (crude but helpful) way of understanding it is to realize that if "a == b" then "a.GetHashCode() == b.GetHashCode()". For objects, "a == b" only if a and b are the same object.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    Then using the hash code in a dictionary would be akin to mapping some unique key to a pointer address in C++. This is not recommended in STL containers (I forget why) but I wonder if it is ok to do in C# generics.

    Also if this hash does map to the handle of the object then why does MS state that the hash codes are not guaranteed to be unique? Wouldn't that mean that two objects share the same handle?

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,175
    Quote Originally Posted by VirtualAce View Post
    Then using the hash code in a dictionary would be akin to mapping some unique key to a pointer address in C++. This is not recommended in STL containers (I forget why) but I wonder if it is ok to do in C# generics.

    Also if this hash does map to the handle of the object then why does MS state that the hash codes are not guaranteed to be unique? Wouldn't that mean that two objects share the same handle?
    It's doubtful the hash table has as many buckets as there are possible memory addresses. The hash function would perform some trickery on the handle and reduce it to a value that could possibly be the same as a different memory address reduces to.
    If you understand what you're doing, you're not learning anything.

  7. #7
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    That makes sense. It probably does a modulus operation to keep the hash within the range of the table which would explain why MS states that the hash is not guaranteed to be unique.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Classes vs Structs
    By afesheir in forum C++ Programming
    Replies: 3
    Last Post: 12-05-2011, 01:52 PM
  2. structs vs classes
    By _Mike in forum C++ Programming
    Replies: 3
    Last Post: 02-06-2010, 11:39 AM
  3. Structs or classes?
    By legit in forum C++ Programming
    Replies: 4
    Last Post: 06-28-2009, 11:16 AM
  4. Classes and Structs
    By mcorn in forum C++ Programming
    Replies: 1
    Last Post: 12-10-2002, 10:11 AM
  5. Classes or Structs?
    By DeanDemon in forum C++ Programming
    Replies: 12
    Last Post: 12-05-2002, 03:58 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21