While trying to implement a GetHashCode override similar to Jon's Skeet's suggestion in What is the best algorithm for an overridden System.Object.GetHashCode? I noticed some odd behavior in the order of evaluation that is causing a syntax error when doing a null check on a collection property in the class using the conditional operator.
Consider the following:
public class Foo
{
public String Name { get; private set; }
public List<String> Bar { get; private set; }
public override Int32 GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + this.Name == null ? 0 : this.Name.GetHashCode();
hash = hash * 23 + this.Bar == null ? 0 : this.Bar.GetHashCode();
return hash;
}
}
}
This code will not compile as you get a syntax error on hash = hash * 23 + this.Bar == null ? 0 : this.Bar.GetHashCode();, specifically pointing too the hash * 23 + this.Bar segment.
The error is
Operator '+' cannot be applied to operands of type 'int' and 'System.Collections.Generic.List'
You do not get the same error on hash = hash * 23 + this.Name == null ? 0 : this.Name.GetHashCode(); although the only difference is Name is a string and Bar is a List<>.
Wrapping the entire conditional operation in a set of parenthesis does remove the error, but that still doesn't explain why the collection property is being treated differently than the string property.
Is there a reason that I'm not aware of that cause the operation to be evaluated differently for different types?