1

I was just creating an helper method to calculate a hash over multiple values based on the answer below:

What is the best algorithm for an overridden System.Object.GetHashCode?

The method is as followed:

static int HashItems(params object[] items)
{
    unchecked
    {
        const int prime1 = 17;
        const int prime2 = 23;

        return items
            .Select(item => item != null ? item.GetHashCode() : 0)
            .Aggregate(prime1, (current, itemHash) => current*prime2 + itemHash);
    }
}

Now this made me wonder what the scope of unchecked really is. Unchecked is something that applies to the currently created function, but since we're using Linq I'm not actually sure what happens. Creating a delegate makes a new class when compiled, but is the unchecked keyword applied to these delegates/classes as well? The documentation is unclear about this (https://msdn.microsoft.com/en-us/library/a569z7k8.aspx).

I'm aware of the following construct though:

static int HashItems(params object[] items)
{
    const int prime1 = 17;
    const int prime2 = 23;

    return items
        .Select(item => item != null ? item.GetHashCode() : 0)
        .Aggregate(prime1, (current, itemHash) => unchecked(current*prime2 + itemHash));
}
Community
  • 1
  • 1
Caramiriel
  • 7,029
  • 3
  • 30
  • 50

1 Answers1

2

(un)checked is a C# level construct. It manifests itself as different IL instructions for arithmetic. So the CLR is not involved in this question. There is no "scope" at the CLR level.

(un)checked is applied using syntactic scope. Any arithmetic instruction that syntactically is in such a scope is being affected. The lambdas are being affected by your use of unchecked.

You probably should prefer the second code block just because it applies the unchecked command closer to the point where it actually takes effect. It's clearer to understand.

usr
  • 168,620
  • 35
  • 240
  • 369