Using boxing ((int)(object)value) instead of pattern matching (value is int intValue) in number classes #102480
-
In the int result;
if (typeof(TOther) == typeof(int))
{
result = (int)(object)value;
}
else if (!TryConvertFromChecked(value, out result) && !TOther.TryConvertToChecked(value, out result))
{
ThrowHelper.ThrowNotSupportedException();
}
return result; I'm interested in this condition in line 3: if (typeof(TOther) == typeof(int))
{
result = (int)(object)value;
} Wouldn't it be better to write it like this: if (value is int intValue)
{
result = intValue;
} As far as I understand it, this would avoid the boxing of However, since I'm seeing this pattern in a lot of places (especially in the TryConvertFromChecked methods), it would seem, I'm missing something here. Why didn't the author use pattern matching here? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
The Pattern matching actually generates more The current JIT is able to optimize both patterns, but optimization for pattern matching is less mature than the well-known special sequence. Ideally, the pattern matching should be done on the type, not the variable. The ultimate solution is proposed at dotnet/csharplang#6308 (comment). |
Beta Was this translation helpful? Give feedback.
The
(ConcreteType)(object)genericVariable
is a special sequence in generic context. It's specially understood by the JIT. The generic mechanism doesn't allow casting a variable typed withT
to be casted to arbitrary destination type. The fake box instruction is to workaround the limitation. Even non-boxable type is also allowed with the special sequence (https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md#special-il-sequences). With generic instantiation, no actual boxing will be performed by this special sequence.Pattern matching actually generates more
box
instructions. See the example at https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBLANgHwAEAmARg…