假设我有这个类(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);
}
现在在Main:
static void Main(string[] args)
{
Boo boo;
Lol(boo, Foo(out boo));
Console.ReadLine();
}
这将导致编译错误:使用未分配的局部变量'boo'。首先,我了解为什么会发生这种情况,我可以通过添加以下内容进行修复:
Boo boo = null;
然后,在我的大声笑方法中,尽管首先执行 Foo ,但boo仍然为空。然后,如果我修改代码以使用 ref 像这样:
Lol(ref boo, Foo(out boo));
static void Lol(ref Boo boo, int n)
{
Console.WriteLine(n);
Console.WriteLine(boo);
}
我得到我是Boo!预期的。我不明白的原因是,如果我更改大声笑中的参数顺序并且不使用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);
这样就不会产生任何编译错误,而且除了我收到“我是Boo!”外,如预期的那样。
在调试时,我注意到在两种情况下(将int参数作为第一个参数,而将另一种方法作为参数)Foo首先执行。那么为什么编译器会显示此错误?
最佳答案
编译器从左到右评估参数表达式。所以在这一行:
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
的堆栈中。关于c# - 编译器错误取决于方法签名中的参数位置。使用未分配的局部变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42027669/