Why does the is-operator cause unnecessary boxing?
The compiler is the same in all cases - Roslyn. Different versions produce different IL though. The C# 8 versions don't box, while older ones do.
For example, with 2.9.0 the IL for this snippet :
using System;
public class C {
public bool IsZero(int value)
{
return value is 0;
}
}
is
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: box [mscorlib]System.Int32
IL_0007: ldarg.1
IL_0008: box [mscorlib]System.Int32
IL_000d: call bool [mscorlib]System.Object::Equals(object, object)
IL_0012: stloc.0
IL_0013: br.s IL_0015
IL_0015: ldloc.0
IL_0016: ret
Using any of the C# 8 versions though produces this in debug mode :
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4.0
IL_0003: ceq
IL_0005: stloc.0
IL_0006: br.s IL_0008
IL_0008: ldloc.0
IL_0009: ret
and this in Release.
IL_0000: ldarg.1
IL_0001: ldc.i4.0
IL_0002: ceq
IL_0004: ret
That's the same as the expected code in the question
is operator Documentation states:
When performing pattern matching with the constant pattern,
is
tests whether an expression equals a specified constant. InC# 6
and earlier versions, the constant pattern is supported by theswitch
statement. Starting withC# 7.0
, it's supported by theis
statement as well.
By default VS2017 using older version C#
compiler. You can enable C# 7.0
features by installing Microsoft.Net.Compilers
from NuGet which can be used to compile the code with the latest version of the compiler.