Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the order of evaluation different for Collections than for other types using the conditional operator

Tags:

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?