假设我有这门课程:
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);
}
现在在Main:
static void Main(string[] args)
{
Boo boo;
Lol(boo, Foo(out boo));
Console.ReadLine();
}
这会产生编译错误:使用未分配的局部变量'boo'。首先,我理解为什么会发生这种情况,我可以通过添加:
来解决这个问题Boo boo = null;
然后,在我的 Lol 方法中,尽管首先执行了 Foo ,但boo仍为null。然后,如果我修改我的代码以使用 ref ,就像这样:
Lol(ref boo, Foo(out boo));
static void Lol(ref Boo boo, int n)
{
Console.WriteLine(n);
Console.WriteLine(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);
然后这不会给出任何编译错误,而且我得到“我是嘘!”正如所料。
在调试时我注意到在两种情况下(将int参数作为第一个并且使用另一种方式)首先执行Foo。那么为什么编译器会显示这个错误?
答案 0 :(得分:3)
编译器从左到右计算参数表达式。所以在这一行:
Boo boo = null;
Lol(boo,Foo(out boo));
首先评估(不ref
)boo
(结果为null
),并将此结果值(null
)放入堆栈作为Lol
的参数。
然后执行Foo(out boo)
,它会设置本地boo
变量的值,但不会更改Lol
的堆栈上的值。
将ref
引用用于本地boo
变量会被置于堆栈中,因此Lol
将读取Foo
更改的值}。
更改参数的顺序时,首先评估/执行Foo(out boo)
,并在将boo
的值放入堆栈Lol
之前初始化{{1}}。