2

可能是一个 C# 菜鸟问题,所以不要激怒我。我试图这样做:

if (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"].ConnectionString != null)
{
    // ...
}

但我一直得到一个System.NullReferenceException. 我想,因为它返回一个字符串,我可以检查null并继续前进。我花了一段时间才找到正确的方法:

ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings["PrimaryConnectionString"];
if (cs != null)
{
    this.Connection.ConnectionString = cs.ConnectionString;
}

所以在其他情况下,比如检查一个Session对象的某个值,我会做这样的检查null

if (Session["EmployeeID"] != null)
{
    _EmployeeID = System.Convert.ToInt32(Session["EmployeeID"]);
}

所以我只是想知道你怎么知道你什么时候可以或不能做检查null

4

4 回答 4

11

您的问题是您正在检查:

ConfigurationManager
    .ConnectionStrings["PrimaryConnectionString"]
        .ConnectionString

对于空指针。

事实上,

ConfigurationManager
    .ConnectionStrings["PrimaryConnectionString"]

为空,因此,当您尝试取消引用以获取连接字符串时,就会出现异常。实际上,您正在做的是:

null.ConnectionString

这是有问题的。

我倾向于避免在单个语句中进行多层取消引用,或者在整个事物周围放置一个异常处理程序以在任何时候捕获问题。

于 2009-07-24T06:09:51.490 回答
4

您的空引用异常发生在父对象 (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"]) 中。一旦你也检查它,你就没事了。

试试这个:

if ((ConfigurationManager.ConnectionStrings["PrimaryConnectionString"] != null)
&& (ConfigurationManager.ConnectionStrings["PrimaryConnectionString"].ConnectionString != null))
  { etc etc }

请注意,如果您从中使用更多方法,则将这些检查分开会很有用。

于 2009-07-24T06:09:33.190 回答
4

您的第一个测试检查 ConnectionStringSettings中的连接字符串是否为空。第二个测试检查 ConnectionStringSettings 引用本身是否为空。这是以下之间的区别:

if (person.Name == null)

if (person == null)

person如果为空,第一个会爆炸;person.Name如果为空,第二个不会发现。如果要同时检查两者,则需要:

if (person == null || person.Name == null)

一些语言(比如 Groovy)有一个 null 安全的解引用操作符,所以你可以这样做:

var x = Expr1?.Expr2?.Expr3?.Expr4;

如果您想测试潜在的长表达式的任何部分是否为空,这使得这种测试更容易。不幸的是C#没有那个:(

于 2009-07-24T06:11:08.600 回答
3

所以我只是想知道你怎么知道你什么时候可以或不能检查null?

可以随时检查是否为空(不可为空的值类型除外,它不能为空)。

应该在希望访问对象成员的任何时候检查 null,并且您不确定包含该对象的变量是否不为 null。

空值检查的几个典型位置是:

  • 你得到一个对象作为你正在编写的函数中的参数传递给你。在使用它之前对参数进行空检查。
  • 您调用返回您希望使用的对象的方法(或获取属性值)。在使用它之前对该返回值进行空检查。
  • NullReferenceException您将一个对象传递给一个方法,其中记录了如果参数为空,它将抛出一个。在调用该方法之前,对您希望传递的变量进行空值检查。
于 2009-07-24T06:14:39.607 回答