c#中的变量范围:未按预期工作

Cod*_*ody 3 .net c# scope

考虑这段代码

class Program
{
    static void Main(string[] args)
    {            
        string str;
        int x;

        for (x = 1; x < 10; x++)
        {
            str = "this";
        }

        Console.WriteLine(str);
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我编译我得到:错误使用未分配的局部变量'str'(我理解这一部分)

如果我将循环更改为if,那么它可以正常工作.为什么这样(在这里迷茫)?

class Program
{
    static void Main(string[] args)
    {            
        string str;
        int x;

        if (true)
        {
            str = "this";
        }

        Console.WriteLine(str);
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

这种不同行为的原因是什么?我预计它应该在两种情况下都给出相同的结果.

我究竟做错了什么 ?

dee*_*see 8

通过静态分析,编译器确定您的if语句将运行str并将被分配.

将您的第二个示例更改为

class Program
{
    static void Main(string[] args)
    {            
        string str;
        int x;
        bool b = true; // With "const bool" it would work, though

        if (b)
        {
            str = "this";
        }

        Console.WriteLine(str);
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

你将拥有与for循环相同的行为.

编译器不确定你的for循环会被执行,即使你知道它会被执行,所以这就是它告诉你未分配变量的原因.在这种情况下,更复杂的编译器可能会看到您的变量很好,但处理所有这些情况是一个非常复杂的问题.

如果x是常量(for由于你想增加它,它在循环中没有意义......)编译器将能够看到1确实小于10并且它不会警告你有关未使用的变量.当然循环现在会永远运行,但我这样说只是为了强调编译器只能确定常量.


Ale*_*exD 6

原因是在第一种情况下,编译器会考虑从不执行循环的情况:

for (x = 1; x < 10; x++)
{
    str = "this";
}
Run Code Online (Sandbox Code Playgroud)

所以它假设str可能保持未初始化.


在第二种情况下,条件总是true如此,因此编译器认为str始终初始化:

if (true)
{
    str = "this";
}
Run Code Online (Sandbox Code Playgroud)