使用-operator()进行常量模式匹配的文档说明:isexpr is constant
常量表达式的计算如下:
如果
expr和constant是整数类型,则C#相等运算符确定表达式是否返回true(即是否返回expr == constant)。否则,表达式的值由对静态
Object.Equals(expr, constant)方法的调用确定。
因此,使用此代码时
public bool IsZero(int value)
{
return value is 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望它使用==运算符(情况1)并生成以下代码:
.method public hidebysig instance bool
IsZero(
int32 'value'
) cil managed
{
.maxstack 8
ldarg.1
ldc.i4.0
ceq
ret
}
Run Code Online (Sandbox Code Playgroud)
但是,实际上,将整数参数和常量(文字)装箱以便传递给静态Object.Equals方法(情况2):
.method public hidebysig instance bool
IsZero(
int32 'value'
) cil managed
{
.maxstack 8
ldc.i4.0
box [mscorlib]System.Int32
ldarg.1
box [mscorlib]System.Int32
call bool [mscorlib]System.Object::Equals(object, object)
ret
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
编译器在所有情况下都是相同的-Roslyn。尽管不同的版本会产生不同的IL。C#8版本不会装箱,而旧版本会装箱。
例如,在2.9.0中,此代码段的IL:
using System;
public class C {
public bool IsZero(int value)
{
return value is 0;
}
}
Run Code Online (Sandbox Code Playgroud)
是
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
Run Code Online (Sandbox Code Playgroud)
尽管使用任何C#8版本都会在调试模式下生成此代码:
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
Run Code Online (Sandbox Code Playgroud)
而这在Release中。
IL_0000: ldarg.1
IL_0001: ldc.i4.0
IL_0002: ceq
IL_0004: ret
Run Code Online (Sandbox Code Playgroud)
与问题中的预期代码相同
| 归档时间: |
|
| 查看次数: |
172 次 |
| 最近记录: |