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

时间:2017-02-03 15:29:15

标签: c# compiler-errors language-design compiler-construction

假设我有这门课程:

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。那么为什么编译器会显示这个错误?

1 个答案:

答案 0 :(得分:3)

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

Boo boo = null;
Lol(boo,Foo(out boo));
首先评估

(不refboo(结果为null),并将此结果null)放入堆栈作为Lol的参数。

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

ref 引用用于本地boo变量会被置于堆栈中,因此Lol将读取Foo更改的值}。

更改参数的顺序时,首先评估/执行Foo(out boo),并在将boo的值放入堆栈Lol之前初始化{{1}}。