在下面的代码中,如果cmd
已初始化,那么我将确保在抛出异常之前关闭所有打开的连接。但是,即使在我检查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'在被赋值之前使用。在运行时可能会产生空引用异常。
应用程序至少有一条可能的路径通过其代码,在分配任何值之前读取变量。
但是我认为在代码中甚至没有一条可能的路径可以在不进行初始化的情况下使用变量。
以下是截图:
这与此处已经提到的许多类似问题不同,例如Prevent Resharper “Possible Null Reference Exception” warnings,因为我不是试图允许NullableType,而是已经保证我的变量不为空。
跟进问题:为什么?
我的对象是否从未初始化或初始化为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
也许编译器在编译时没有很好的方法来保证这一点。
答案 0 :(得分:4)
您的问题不是您的值为null,问题是您的对象根本没有初始化。例如:
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");
}
}
它会起作用,因为我的列表现在有一个值,它是null,但它仍然存在。
编辑:对不起我使用C#而不是VB,那是因为我编写的编辑器很方便,但代码是正确的。 你每次都初始化你的变量,你不会得到错误。答案 1 :(得分:3)
如果你把
Dim cmd As SqlCommand = Nothing
应该没问题。