0

Moving from Java to C# developer. In Java, I used a lot of Objects.hash(array) and Objects.hashCode(object) to build hash code of an object in hashCode function. I can't find any equivalent for those functions in C#. Any ideas?

Indeed I can call GetHashCode and combine them as shown in Concise way to combine field hashcodes?, but that requires a lot of null checks for reference types and that is making code much longer than comparable Java code.

In Java:

public class MyObject {

    private Integer type;
    private String[] attrs;
    
    @Override
    public int hashCode() {
        int hash = 1, p = 31;
        hash = p * hash + Objects.hashCode(type); // Handle Null case
        hash = p * hash + Objects.hash(attrs); // Handle Null case
        return hash;
    }
}

In C#:

public class MyObject {

    private int? type;
    private string[] attrs;
    
    public override int GetHashCode()
        int hash = 1, p = 31;
        hash = p * hash + hash_of(type);    // Any utilities?
        hash = p * hash + hash_of_array(attrs); // Any utilities?
        return hash;
    }
}

Note: I'm not looking for compatible results (as I know that hash codes would be different for similar objects, and can be different even between versions/platform for the same framework) but rather code size & concise way.

LHA
  • 9,398
  • 8
  • 46
  • 85
  • Every object in .Net implements GetHashCode. Are you asking for something else? –  Sep 18 '19 at 17:46
  • @Amy: GetHashCode only came with default implementation. We still need to override it if we want use the object as map key or put the object into a hash set. See this: https://learn.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=netframework-4.8 – LHA Sep 18 '19 at 17:48
  • What "correct" implementation? .Net hash codes are not going to be the same as Java hash codes. They are used for hash sets all the time without issue. –  Sep 18 '19 at 17:50
  • Why not the same? You are understanding wrong about object hash code and why we need it... – LHA Sep 18 '19 at 17:54
  • You're right, I don't understand why the default implementation works for everyone else, but not for you. –  Sep 18 '19 at 17:54
  • I didn't say ANY C# objects we need to override getHashCode(). ONLY override for some cases. – LHA Sep 18 '19 at 17:55
  • If those classes need a special hash code, those classes will have implemented it. If its your class, you can implement it, as you have. The default hash code function works fine. It's very unclear why it won't. –  Sep 18 '19 at 17:56
  • No. Default hash code does not work fine in my case if I want to put MyObject into a SET and use IndexOf function – LHA Sep 18 '19 at 17:57
  • I already said the default hash code works just fine with sets. Can you explain why you think it won't? –  Sep 18 '19 at 17:58
  • If you read https://learn.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=netframework-4.8, you will understand WHY – LHA Sep 18 '19 at 18:01
  • I am familiar with that documentation, and have used .Net and `GetHashCode` with sets for *years*. Why don't you just call `type.GetHashCode()` and `attrs.GetHashCode()` and call it a day? Please explain why it works for everyone but not in your case. –  Sep 18 '19 at 18:02
  • Yes. It works but I have to handle NULL before calling GetHashCode.... – LHA Sep 18 '19 at 18:04
  • Yes, that is how you do it. You can't call a method on a null object, so if its null, avoid calling that method. You'll need to handle null values using an `if` conditional statement or null coalescing, or the null member propagation operator, or something else. –  Sep 18 '19 at 18:08
  • Yes. I can do that BUT it is not CONCISE way. that is why Java has Objects.hash and Objects.hashCode utility. – LHA Sep 18 '19 at 18:09
  • Oh, it's not concise. Of course, I see that now in the `GetHashCode` documentation you wanted me to read. I understand the issue now. –  Sep 18 '19 at 18:13
  • @AlexeiLevenkov, I'm not sure why you have added the last sentence. I think the only reason someone would want to implement same hashcode inter-language (Java, C#, PHP ...) would be to comparing objects when it travels between systems. I have similar algorithm to compare java hashcode in PHP and need exact same hash calculation in .NET too. – AaA Nov 19 '21 at 03:55

1 Answers1

4

The .NET equivalent of this is the new System.HashCode, in particular the HashCode.Combine<> method which you can use to create a hash code from multiple values:

public class MyObject
{
    private int? type;
    private string[] attrs;

    public override int GetHashCode()
        => HashCode.Combine(type, attrs);

    // remember to also override Equals
}

Note that this type is only available in .NET Core. If you are running on .NET Framework, you will have to implement the hash code calculation yourself. Good ways to do that are documented here.

poke
  • 369,085
  • 72
  • 557
  • 602