代码之家  ›  专栏  ›  技术社区  ›  BlackTigerX Borut Tomazin

IDisposable:是否需要在finally{}上检查null?

  •  11
  • BlackTigerX Borut Tomazin  · 技术社区  · 16 年前

    在大多数的例子中,你可以在网上找到 不使用 “使用”模式类似于:

      SqlConnection c = new SqlConnection(@"...");
      try {
        c.Open();
      ...
      } finally {
        if (c != null) //<== check for null
          c.Dispose();
      }
    

    L_0024: ldloc.1 
    L_0025: ldnull 
    L_0026: ceq 
    L_0028: stloc.s CS$4$0000
    L_002a: ldloc.s CS$4$0000
    L_002c: brtrue.s L_0035
    L_002e: ldloc.1 
    L_002f: callvirt instance void [mscorlib]System.IDisposable::Dispose()
    L_0034: nop 
    L_0035: endfinally 
    

    4 回复  |  直到 16 年前
        1
  •  12
  •   Jon Skeet    16 年前

    “using”语句可以用构造函数以外的调用初始化变量。例如:

    using (Foo f = GetFoo())
    {
        ...
    }
    

    在这里 f 返回null。这就是为什么 using 语句检查是否为空。这与区块内部的东西无关,因为 使用 语句保留原始初始值。如果你写:

    Stream s;
    using (s = File.OpenRead("foo.txt"))
    {
        s = null;
    }
    

    然后流仍将被处理(如果变量为 宣布 使用

    对你来说,你知道的 c 在输入 try 块,则不需要在 finally 阻止,除非你重新分配它的值(我真心希望你不是!)在街区内。

    现在用你现在的代码 在对的赋值之间引发异步异常的轻微风险 然后进入 尝试 块-但是很难完全避免这种竞争条件,因为在构造函数完成之后,但在将值赋给 C

    你有什么理由不想只使用using语句吗?老实说,我很少自己写 最后


    看到马克的回答就哭了。但通常并不相关。

        2
  •  5
  •   to StackOverflow    16 年前

    在您的示例中,检查null是不必要的,因为c在显式构造之后不能为null。

    在下面的示例中(类似于using语句生成的内容),当然需要检查null:

    SqlConnection c = null; 
      try { 
        c = new SqlConnection(@"..."); 
        c.Open(); 
      ... 
      } finally { 
        if (c != null) //<== check for null 
          c.Dispose(); 
      } 
    

    此外,在以下情况下需要检查null,因为您不能确定CreateConnection不会返回null:

    SqlConnection c = CreateConnection(...); 
      try { 
        c.Open(); 
      ... 
      } finally { 
        if (c != null) //<== check for null 
          c.Dispose(); 
      } 
    
        3
  •  2
  •   Community Mohan Dere    9 年前

    乔恩已经讲到了要点。。。但只是一个随机的琐事;你的 建造师 null . 不是很常见的情况,当然也不是 using 不应该 折磨你的密码-但是 it can happen MyFunnyProxy ).

        4
  •  0
  •   Gishu    16 年前

    有趣。。我使用的是VS2010,通过我的自定义代码片段(R:)——使用的是rock块。

    • compiler error CS1656
    • 接下来在try块中,没有规则,可以将null赋给变量。因此,在finally块中必须在Dispose之前执行null检查。