I am curious to know why this is happening. Please read the code example below and the corresponding IL that was emitted in comments below each section:
usi
The compiler doesn't know the real type of o in the first expression, but it does know the real type in the second expression. It looks like it's only looking at one statement at a time.
This is fine, because C# depends heavily on the JIT for optimization. It's very likely in such a simple case that both calls will become instance calls at runtime.
I don't believe callvirt is ever emitted for non-virtual methods, but even if it was, it would be no problem because the method would never be overridden (for obvious reasons).