2

这是:

if (myLongValue > 0) // 0 is displayed as int in Visual Studio tooltip

等于:

if (myLongValue > 0L)

这是使用特殊的操作码吗?(类似于 JZ - 如果在 x86 asm 中为零则跳转)。

4

2 回答 2

4

2 在 IL 方面完全等效。让我们以下面的代码片段为例:

public static void Main(string[] args)
{
    long myLongValue = long.Parse("123");
    if (myLongValue > 0)
    {
        Console.WriteLine("ok");
    }
}

它被编译为以下 IL(在发布模式下):

.method public hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] int64 myLongValue)
    L_0000: ldstr "123"
    L_0005: call int64 [mscorlib]System.Int64::Parse(string)
    L_000a: stloc.0 
    L_000b: ldloc.0 
    L_000c: ldc.i4.0 
    L_000d: conv.i8 
    L_000e: ble.s L_001a
    L_0010: ldstr "ok"
    L_0015: call void [mscorlib]System.Console::WriteLine(string)
    L_001a: ret 
}

现在替换if (myLongValue > 0)if (myLongValue > 0L),您将获得严格等效的 IL。

一个更优化的 IL 应该是这样,但不幸的是我无法让编译器发出它:

.method public hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] int64 myLongValue)
    L_0000: ldstr "123"
    L_0005: call int64 [mscorlib]System.Int64::Parse(string)
    L_000a: stloc.0 
    L_000b: ldloc.0 
    L_000c: ldc.i8.0 
    L_000d: ble.s L_001a
    L_0010: ldstr "ok"
    L_0015: call void [mscorlib]System.Console::WriteLine(string)
    L_001a: ret 
}

这里我们不需要conv.i8指令,因为我们直接将提供的 Int64 类型的值作为 int64 推入评估堆栈。

于 2013-03-31T15:11:45.873 回答
1

在您的第一个示例中,运算符>的左侧为long( System.Int64),右侧为int( System.Int32)。由于 C# 规范没有定义具有该签名的运算符的重载>,因此我们必须检查某些转换是否适用于一个(或两个)参数(操作数)。

存在从到的隐式转换。另一个方向的转换不是隐式的。因此,右侧通过加宽转换进行转换,并使用重载。intlongoperator >(long x, long y)

由于在这种情况下,右侧int是编译时文字,编译器可以扩展常量,因此编译后的两个示例之间没有区别。另一个答案展示了输出 IL 的样子。

那么如果你有:

ulong myULongValue = XXX;
if (myULongValue > 0)
    ...

一般来说,没有从(signed) 到(unsigned)的隐式转换。但是,当是一个恰好为非负的编译时常量(字面量)时,确实存在转换。所以我上面的例子仍然有效(并产生与 相同的结果)。intulongintif (myULongValue > 0ul)

但是对于非常量int,它必须失败:

ulong myULongValue = XXX;
int zero = 0;               // not const
if (myULongValue > zero)    // will NOT compile!
    ...
于 2013-03-31T15:45:55.873 回答