从方法返回一次性对象时的CA2000

Bri*_*ett 14 c# code-analysis idisposable ca2000

我有一个工厂方法来构建实现的对象IDisposable.最终,调用者可以管理创建对象的生命周期.这种设计引发了一堆CA2000错误.在我的设计中是否存在根本不正确的东西,是否需要重构,还是仅仅对静态代码分析警告过于兴奋?

工厂方法

public static DisposableType BuildTheDisposableType(string param1, int param2)
{
    var theDisposable = new DisposableType();

    // Do some work to setup theDisposable

    return theDisposable
}
Run Code Online (Sandbox Code Playgroud)

来电者

using(var dt = FactoryClass.BuildTheDisposableType("data", 4))
{
   // use dt
}    
Run Code Online (Sandbox Code Playgroud)

Mik*_*l X 17

您应该将它存储到本地变量,并在try-catch-rethrow块中包装初始化,以防出现任何异常:

public MyDisposable CreateDisposable()
{
    var myDisposable = new MyDisposable();
    try
    {
        // Additional initialization here which may throw exceptions.
        ThrowException();
    }
    catch
    {
        // If an exception occurred, then this is the last chance to
        // dispose before the object goes out of scope.
        myDisposable.Dispose();
        throw;
    }
    return myDisposable;
}
Run Code Online (Sandbox Code Playgroud)

Dispose不会被调用时,尽量不要让一次性对象容易受到异常的影响

PS:之前提到的有人在最后处理 - 这显然是错误的 - 在非异常路径中你不想打电话 Dispose

  • DavidRR,这没什么区别.如果是new中的异常,则不会调用赋值,即myDisposable不会被更改 - 因此无需释放. (3认同)
  • @String.Empty 此答案中的示例不应导致 CA2000 问题。如果遵循此模式后您仍然看到 CA2000,则一定有其他原因在起作用。在这种情况下,最好发布一个新的堆栈溢出问题,其中包含有关代码的更多详细信息。 (2认同)

Joh*_*ers 10

我建议您在每个单独的工厂方法上抑制CA2000警告,或者可能在包含它们的整个类上抑制CA2000警告(但仅当它是该类的唯一函数时).

我进一步建议你包括一个理由:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability",
    "CA2000:Dispose objects before losing scope",
    Justification = "This is a factory method. Caller must dispose")]
Run Code Online (Sandbox Code Playgroud)

  • CA2000实际上没有返回一次性对象和调用者获得所有权的方法的问题.它试图在这里告诉我们,有一个执行路径,一次性物体不会正确地传递给来电者,所以**这不是误报 - 不要压制**!@MiklX发布了正确的答案,我已经清理了一下以澄清. (7认同)