Let’s say we have a value type like this, where the fields are readonly and initialized during construction:
public struct SomeValue
{
private readonly Int32 field1;
private readonly Int32 field2;
...
}
Also, let’s say we have a helper class that lets us implement GetHashCode() for composite types in a reusable manner:
public struct SomeValue
{
...
public override Int32 GetHashCode()
{
return HashHelpers.GetHashCode(this.field1, this.field2);
}
}
Now, the compiler must realize that the field values aren’t ever going to change after the type is constructed, since they are readonly. Is it therefore likely that the call to HashHelpers.GetHashCode() will somehow be inlined when SomeValue.GetHashCode() is JIT-ed?
You didn’t post the code for your HashHelper method, but since it should be small and fast, yes, it is quite likely that it will get inlined.
And, yes, the JIT optimizer is quite capable of evaluating expressions at compile time and replace the code with a simple constant value. But that is not going to happen when you use a readonly member. Because the value it has is determined by the constructor. The optimizer does not consider the code in other methods to guess if the field has a known value. It must be able to detect the value when it compiles GetHashCode.
You can get this if you use a const to initialize the readonly field. And use that same const in the GetHashCode implementation. That’s pretty ugly. Given the very limited benefit you’ll get from this micro-optimization, this is probably not something you should consider. The possible win is no more than a nano-second or so. But most likely zero because the optimizer would replace a xor with a mov.