返回引用值时出现不明确的行为

本文关键字:不明确 引用 返回 | 更新日期: 2023-09-27 18:24:55

我有一段代码:

using System;
public class Program
{
    private static int Incr(ref int i)
    {
        return i++;
    }
    public static void Main()
    {
        var i = 0;
        i += Incr(ref i);
        Console.WriteLine(i);
    }
}

Console.WriteLine(i)将给我们"0"。但调用Incr(参考i)时没有"+="

var i = 0;
Incr(ref i);
Console.WriteLine(i);

会给我们"1"。这怎么可能?

返回引用值时出现不明确的行为

i += Incr(ref i)视为

i = i + Incr(ref i);

换句话说:

  • 评估i
  • 呼叫Incr(ref i)
  • 将两个操作数相加
  • 分配给i

现在Incr(ref i)i设置为1,但返回0…因此总和最终为0+0,然后将其分配给i。在返回Incr和将结果分配回i之间的时间内,i的值非常暂时地为1。

如果你有:

int j = i + Incr(ref i);

那么你最终会得到j=0, i=1

当您调用Incr(ref i)时,Incr递增i(因此i为1),然后忽略返回值。。。因此CCD_ 16之后为1。

在其他新闻中:应该不惜一切代价避免这样的代码。

代码的作用:

  • 编译器内部重写:i += Incr(ref i);变成i = i + Incr(ref i);(毕竟+=就是这么做的)
  • 评估i +。CCD_ 21为0结果A
  • 调用Incr(ref i),其中i为0
  • 返回i。CCD_ 25仍然为0结果B
  • 返回值后,通过执行i++来增加i。由于i通过为ref:i为1,但i在评估中没有发挥任何作用,因为i +已经被评估了
  • 将结果A(0)添加到结果B(0)。结果:0