Over a million developers have joined DZone.

The Innocuous Code That Tripped Me

DZone's Guide to

The Innocuous Code That Tripped Me

Sometimes the code that breaks on us when we believe it shouldn't breaks because of something we've long since stopped thinking about.

Free Resource

Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.

When building a cache, I need a way to generate a hash code from a query. A query is a complex object that has many properties. My first attempt to do so looked like this:

public int GetHashCode()
  int hashCode = QueryStr.GetHashCode();
  hashCode = (hashCode * 397) ^ WaitForNonStaleResultsTimeout?.GetHashCode() ?? 0;
  hashCode = (hashCode * 397) ^ AllowStale.GetHashCode();
  return hashCode;

And it failed, disastrously. All queries always had the same hash code, and I couldn’t figure out why until I actually debugged through the code.

Here is a hint: this only happened if WaitForNonStaleResultsTimeout is null. It might be better to also look at the way the compiler looks at this:

public unsafe override int GetHashCode()
    int num = this.QueryStr.GetHashCode() * 397;
    TimeSpan?* expr_18 = ref this.WaitForNonStaleResultsTimeout;
    return ((num ^ 
      (expr_18.HasValue ?
          new int?(expr_18.GetValueOrDefault().GetHashCode()) : null)) ?? 0
        ) * 397
        ^ this.AllowStale.GetHashCode();

Basically, if WaitForNonStaleResultsTimeout is null, the entire expression evaluated to null, so we return zero, losing all the previous hash values that we put in.

The solution was to parenthesis the expression, but this is something that passed a couple rounds of scrutiny and didn’t show up at all, because it looked fine, and I don’t keep the precedence rules for operators in C# in my head.

What’s the best way to boost the efficiency of your product team and ship with confidence? Check out this ebook to learn how Sentry's real-time error monitoring helps developers stay in their workflow to fix bugs before the user even knows there’s a problem.

c# ,ravendb ,performance ,query ,hash code

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}