编译器错误取决于方法签名中的参数位置。使用未分配的局部变量

Compiler error depending on parameter position in method signature. Use of unassigned local variable

假设我有这个 class:

class Boo
{
    public override string ToString()
    {
        return "I am Boo!";
    }
}

还有这些方法:

static int Foo(out Boo boo)
{
    boo = new Boo();
    return 1;
}
static void Lol(Boo boo, int n)
{
    Console.WriteLine(n);
    Console.WriteLine(boo);
}

现在主要:

static void Main(string[] args)
{
    Boo boo;
    Lol(boo, Foo(out boo));
    Console.ReadLine();
}

这给出了编译错误:使用未分配的局部变量'boo'。首先,我明白为什么会这样,我可以通过添加来解决它:

Boo boo = null;

然后,在我的 Lol 方法中,尽管首先执行了 Foo,但 boo 仍然为空。然后,如果我修改代码以使用 ref,如下所示:

Lol(ref boo, Foo(out boo));
static void Lol(ref Boo boo, int n)
{
    Console.WriteLine(n);
    Console.WriteLine(boo);
}

我得到了 我是 Boo! 正如预期的那样。我不明白的是,如果我更改 Lol 中参数的顺序并且不使用 ref 并且不初始化 boo 的原因如下:

static void Lol(int n, Boo boo) //order of the parameters has changed
{
    Console.WriteLine(n);
    Console.WriteLine(boo);
}

Lol(Foo(out boo), boo);

然后这不会给出任何编译错误,而且我得到了预期的 "I am Boo!"。

在调试时我注意到在这两种情况下(第一个是 int 参数,另一个是另一个)Foo 首先执行。那为什么编译器会显示这个错误呢?

编译器从左到右计算参数表达式。所以在这一行中:

Boo boo = null;
Lol(boo,Foo(out boo));

(without ref) boo 首先计算(结果为 null),结果为 value (null) 作为 Lol.

的参数放入堆栈

然后执行 Foo(out boo) 设置本地 boo 变量的值但不会更改已在堆栈上的 Lol.

的值

使用 ref 对本地 boo 变量的 引用 被放入堆栈,因此 Lol 将读取更改后的值通过 Foo.


更改参数顺序时,Foo(out boo) 首先是 evaluated/executed,boo 在将其值放入堆栈之前初始化 Lol