Visual Studio 空引用警告 - 为什么没有错误?

问题描述 投票:0回答:4

我注意到 Visual Studio 的一些奇特之处。首先,尝试在函数中的某个位置键入此 (C#):

class Foo  
{  
    public void Bar()  
    {  
        string s;
        int i = s.Length;
    }
}

现在,它会立即将

s
中的
s.Length
标记为错误,并显示“
Use of unassigned local variable 's'
”。另一方面,试试这个代码:

class Foo  
{  
    private string s;
    public void Bar()  
    {  
        int i = s.Length;
    }
}

它将编译,并在

s
中的
private string s
下划线并带有警告,表示“
Field 'Foo.s' is never assigned to, and will always have its default value null
”。

现在,如果 VS 那么聪明并且知道 s 将始终为 null,那么为什么在第二个示例中获取它的长度不是错误呢?我最初的猜测是,“如果编译器根本无法完成其工作,它只会给出编译错误。从技术上讲,只要您从不调用 Bar(),代码就会运行,所以它只是一个警告。”但第一个示例的解释无效。只要您从不调用 Bar(),您仍然可以运行代码而不会出现错误。那么什么给出呢?只是一个疏忽,还是我错过了什么?

c# visual-studio nullreferenceexception
4个回答
8
投票

第一个示例(错误)是编译器的“定义赋值”跟踪的示例,仅适用于局部变量。由于上下文有限,编译器对这种情况有严密的控制。请注意,s不为空,它是未定义的。


在第二个示例中,

s

是一个字段(默认为 null)。没有编译器错误,但总是会在运行时捕获。 这种特殊情况可能会被捕获,但编译器通常无法检测到这种错误。

例如,您可以添加一个方法 
Bar2()
,将字符串分配给
s
,但晚于
Bar()
调用它,或者根本不调用它。这将消除警告,但不会消除运行时错误。

所以这是设计使然。


3
投票

编译器并非100%正确。 如果通过反射修改实例,“s”可能具有非空值。
  • 如果从未调用 Bar 方法,程序可以无错误地执行
  • 该程序可能是一个测试程序,出于测试原因触发 NullReferenceException

0
投票


0
投票
s

是一个局部变量,编译器可以轻松检查s变量在使用之前是否未被分配。 在第二个中,

s

是一个全局变量,它可能是在类中的其他地方初始化的。

© www.soinside.com 2019 - 2024. All rights reserved.