gpt4 book ai didi

c# - 为什么 is-operator 会导致不必要的装箱?

转载 作者:可可西里 更新时间:2023-11-01 08:27:19 26 4
gpt4 key购买 nike

documentationis 运算符(expr is constant)的常量模式匹配状态:

The constant expression is evaluated as follows:

  1. If expr and constant are integral types, the C# equality operator determines whether the expression returns true (that is, whether expr == constant).

  2. Otherwise, the value of the expression is determined by a call to the static Object.Equals(expr, constant) method.


因此,在使用这段代码的时候

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
}

为什么会这样?

最佳答案

编译器在所有情况下都是相同的 - Roslyn。虽然不同的版本产生不同的 IL。 C# 8 版本不装箱,而旧版本则装箱。

例如,2.9.0此代码段的 IL:

using System;
public class C {

public bool IsZero(int value)
{
return value is 0;
}
}

    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

使用任何 C# 8 versions虽然在 Debug模式下产生这个:

    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

这在 Release 中.

    IL_0000: ldarg.1
IL_0001: ldc.i4.0
IL_0002: ceq
IL_0004: ret

这与问题中的预期代码相同

关于c# - 为什么 is-operator 会导致不必要的装箱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56561692/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com