【发布时间】:2019-10-26 22:30:37
【问题描述】:
documentation 与 is 运算符 (expr is constant) 的常量模式匹配状态:
常量表达式的求值如下:
如果
expr和constant是整数类型,则C# 相等运算符确定表达式是否返回true(即是否返回expr == constant)。否则,表达式的值由调用静态
Object.Equals(expr, constant)方法确定。
因此,当使用此代码时
public bool IsZero(int value)
{
return value is 0;
}
我希望它使用== 运算符(案例1)并生成此代码:
.method public hidebysig instance bool
IsZero(
int32 'value'
) cil managed
{
.maxstack 8
ldarg.1
ldc.i4.0
ceq
ret
}
但是,在reality 中,整数参数和常量(字面量)被装箱以便传递给静态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
}
为什么会这样?
【问题讨论】:
-
也许this 有帮助
-
@SᴇM 你用的是什么编译器?对我来说,VS17 和 SharpLab(参见 here)都会产生问题中存在的 CIL。
-
@ThomasFlinkow 您使用什么框架版本?我刚刚注意到,如果我从
4.6.1更改为4,它会将值框起来。 -
@ThomasFlinkow 你可以使用 Sharplab.io 来尝试不同的编译器。你是对的,旧的 Roslyn 版本做盒子,而实现 C# 8 功能的 newer 没有
-
抱歉,这只是 VS 版本之间的区别(还有
c#版本)。我相信这是因为新的Pattern Matching 功能,它显然在没有装箱的情况下检查值类型的类型。