代码之家  ›  专栏  ›  技术社区  ›  KyleMit Steven Vachon

检查null时禁用null引用警告

  •  4
  • KyleMit Steven Vachon  · 技术社区  · 10 年前

    在以下代码中,如果 cmd 已初始化,则我将确保在引发异常之前关闭所有打开的连接。然而,即使在我检查之后 命令 不为空,我仍然会在后续代码行中收到可能的空引用警告。

    Dim cmd As SqlCommand
    Try
        'Do some Stuff
    Catch ex As Exception
        If cmd IsNot Nothing AndAlso
           cmd.Connection IsNot Nothing AndAlso              '<- null cmd warning 
           cmd.Connection.State = ConnectionState.Open Then  '<- null cmd warning 
            cmd.Connection.Close()                           '<- null cmd warning 
        End If
        Throw
    End Try
    

    我收到以下两个警告(可能一个来自Resharper,一个来自Visual Studio):

    • 变量“x”在访问之前可能未初始化。运行时可能发生空引用异常。
    • BC42104:变量“x”在赋值之前使用。运行时可能会导致空引用异常。

    根据 Visual Studio Page :

    应用程序在代码中至少有一条可能的路径,该路径在为变量赋值之前读取变量。

    但我不认为在代码中有一条可能的路径可以在不初始化的情况下使用变量。

    • 我犯了什么错误还是这是个错误?
    • 有没有办法阻止出现此警告?

    下面是一张截图:

    screenshot

    这与这里已经提出的许多类似问题不同,例如 Prevent Resharper “Possible Null Reference Exception” warnings 因为我没有尝试允许NullableType,而是已经保证了我的变量不为null。


    更新:

    后续问题:为什么?

    我的对象是否从未初始化或初始化为 Nothing ,在这两种情况下 cmd IsNot Nothing 应决心 False ,所以在 AndAlso 不应执行。

    Dim cmd1 As SqlCommand
    Console.Write(cmd1 IsNot Nothing) 'False
    
    Dim cmd2 As SqlCommand = Nothing
    Console.Write(cmd2 IsNot Nothing) 'False
    

    也许编译器在编译时没有很好的方法来保证这一点。

    2 回复  |  直到 4 年前
        1
  •  4
  •   Fedor Hajdu    10 年前

    你的问题不是你的值为空,而是你的对象根本没有初始化。例如:

        static void Main(string[] args)
        {
            List<int> empty;
    
            if (empty != null)
            {
                Console.WriteLine("no");
            }
        }
    

    将不编译 因为 empty 没有价值。如果我将代码更改为:

        static void Main(string[] args)
        {
            List<int> empty = null;
    
            if (empty != null)
            {
                Console.WriteLine("no");
            }
        }
    

    它会起作用,因为我的列表现在有一个值,它是空的,但它仍然存在。

    编辑:对不起,我用了C#而不是VB,这是因为我手边有编辑器,但代码是正确的。 每次初始化变量都不会出错。

        2
  •  3
  •   trucker_jim    10 年前

    如果你把

    Dim cmd As SqlCommand = Nothing
    

    应该没事。。