【问题标题】:Any way to know if calling method should Dispose the object returned by called method知道调用方法是否应该处理被调用方法返回的对象的任何方法
【发布时间】:2014-11-21 07:19:44
【问题描述】:

有没有办法标记一个方法,以便代码分析或构建给出错误消息来处理方法返回的对象。例如在下面的方法中。

  private void chart1_Click(object sender, EventArgs e)
    {
        Brush sb = GetBlackBrush();
    }

    Brush GetBlackBrush()
    {
        SolidBrush sb = new SolidBrush(Color.Black);
        return sb;
    }

每当调用 GetBlackBrush 的任何方法,在 VS2010 中构建解决方案时,我都会收到代码分析警告或构建错误或构建警告,以指示我需要处理 Brush 对象。我希望我应该在 chart1_Click() 方法中得到一些指示来处理画笔对象。

这只是一个示例代码,我知道我们应该使用 "Using" 但这里有什么解决方案。

有一个 CA2213 代码分析警告,但在这个特定示例中没有被调用。

【问题讨论】:

  • 你真的不想立即处理它,是吗?
  • 在这种情况下,代码分析无法判断您是否需要处置该对象。该方法返回对象,这通常意味着它应该被释放,因为您正在将它交给其他代码。因此,在您的示例中,您应该使用using。通常,代码分析可以很好地识别未处理的对象以及离开方法的对象。你有没有更合理的例子,代码分析没有发现真正的错误?
  • 这是一个真实的例子,如果你在任何其他方法中使用GetBlackBrush()这个方法,代码分析不会出错。代码分析没有给出错误。
  • 请准确发布您使用GetBlackBrush编写的代码,并且不会在代码分析中引起警告。
  • 为什么你会期望 CA2213 = "Disposable fields should be dispose" 对于这个示例?它不包含任何一次性字段,仅包含一次性本地引用。不过,我希望在 chart1_Click 方法上看到 CA2000 =“在失去范围之前处理对象”。

标签: c# dispose static-code-analysis


【解决方案1】:

CA2000 警告是您可能需要的,请参阅documentation

如果一次性对象没有在所有 对它的引用超出范围,该对象将被放置在某个位置 垃圾收集器运行终结器的不确定时间 物体。因为可能会发生异常事件,这将阻止 从运行对象的终结器,该对象应该是 而是显式处置。

不确定您是否可以将其标记为错误,但它应该会捡起它。 您可能还想启用CA2213

【讨论】:

  • 你对 CA2213 是正确的,但试试这个例子,运行代码分析后我没有得到 CA2213。
  • 我刚刚检查过它,在一种情况下(在同一个班级)它显示警告,而在另一种情况下(IDisposable 在班级外创建)它不是。我正在使用 VS2013
【解决方案2】:

没有特定的约定来指示哪些方法转移IDisposable 对象的所有权,并且框架本身在这方面相当不一致。如果一个方法创建并返回一个对新SolidBrush 的引用而不保留该引用的副本,那么该画笔的接收者应该处置它。如果相反,该方法做了类似的事情:

WeakReference<Brush> myBrush = new WeakReference<Brush>(); // Field of class hosting method

Brush GetBlackBrush()
{
  Brush ret = myBrush.Target;
  if (ret == null)
  {
    ret = new SolidBrush(Color.Black);
    myBrush.Target = ret;
  }
}

那么正确性将表明接收者在它收到的对象上调用Dispose [使用弱引用将确保在任何时候上述代码只会泄漏成为一个额外的SolidBrush 对象;如果调用者放弃了实例而不处置它,那么通常 GC 不会注意到该实例已被放弃(在这种情况下,下一个调用者将收到相同的实例),或者它已经清理了它。在任何一种情况下,一次只会存在一个被放弃的画笔实例。此外,在画笔实例上调用DisposemyBrush 持有对它的引用会破坏GetBlackBrush() 的下一个调用者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    相关资源
    最近更新 更多