【问题标题】:Explicit Conversion to IDisposable显式转换为 IDisposable
【发布时间】:2011-07-02 12:18:43
【问题描述】:

我正在使用一些 XmlReaderXmlWriter 对象对一些 try...catch 块内的字符串做一些必要的工作。

我知道使用符号using (XmlReader NewReader = XmlReader.Create(...)) 是首选语法,但我不太喜欢这样,所以我还要附加finally 块并执行NewReader.Close();NewWriter.Close();

然而,代码分析 抱怨这些对象没有被释放,从而迫使我以某种方式调用Dispose() 方法。

问题是在这些类中Dispose() 方法是显式实现的,所以我必须使用((IDisposable)(NewReader)).Dispose();((IDisposable)(NewWriter)).Dispose();

这种技术有什么缺点吗?

【问题讨论】:

  • 你为什么不想使用 using 语句。它可以完成您需要做的所有事情,您不会收到 fxcop 警告并且它比使用 try-finally 更简洁。

标签: c# .net idisposable explicit-implementation


【解决方案1】:

不使用using有充分的理由:

  • 当对象的生命周期可能需要比当前块存活的时间更长时

避免using的理由不足:

  • “我不太喜欢那样”

充分的理由适用于您的代码吗?

还请注意,一个简单的扩展方法会使语法变得又好又干净。

【讨论】:

    【解决方案2】:

    C# using 语句将始终为您调用 Dispose。它大致翻译成以下内容:

    XmlReader NewReader = XmlReader.Create(...);
    try
    {
       // do stuff on NewReader 
    }
    finally
    {
        ((IDisposable)NewReader).Dispose();
    }
    

    因此,将其包装在 finally 中不会增加任何价值。尽管CloseDispose 通常是等价的,但并非总是如此。因为这个 FxCop 是对的,你应该总是调用Dispose,当你这样做(或者让using 语句这样做)时,没有理由手动调用Close

    【讨论】:

      【解决方案3】:

      using 语句确实是首选解决方案。它在 C# 中是惯用的。这些类显式地实现了IDisposable,因为它们已经提供了一个具有关闭语义的方法:Close。我敢打赌Dispose 会调用Close,反之亦然。 但你不应该指望这一点,无论如何都应该打电话给Dispose

      最后,所有这些都是等价的:

      1. 使用using,这是首选;
      2. finally 块上调用Close,并禁止静态分析警告或;
      3. 拨打Disposefinally((IDisposable)NewReader).Dispose();

      【讨论】:

      • 不幸的是,CloseDispose 的行为并不总是相同的。除了关闭的实例通常可以重新打开而处置的实例不能重新打开的明显区别之外,某些对象在调用Close(例如SqlConnection)时不会抑制终结,这会迫使您无论如何都要调用Dispose以防止GC 的额外压力。
      猜你喜欢
      • 1970-01-01
      • 2011-07-31
      • 2020-08-12
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 2013-11-17
      相关资源
      最近更新 更多