简体   繁体   English

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

[英]CA2000 when Returning Disposable Object from Method

I have a factory method that builds objects that implement IDisposable . 我有一个工厂方法,可以构建实现IDisposable对象。 Ultimately it is the callers that manage the lifetime of the created objects. 最终,调用者可以管理创建对象的生命周期。 This design is triggering a bunch of CA2000 errors . 这种设计引发了一堆CA2000错误 Is there something fundamentally incorrect in my design, does it need refactoring, or is it just getting too excited about static code analysis warnings? 在我的设计中是否存在根本不正确的东西,是否需要重构,还是仅仅对静态代码分析警告过于兴奋?

The factory method 工厂方法

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

    // Do some work to setup theDisposable

    return theDisposable
}

A caller 来电者

using(var dt = FactoryClass.BuildTheDisposableType("data", 4))
{
   // use dt
}    

You should store it to local variable, and wrap initialization in the try-catch-rethrow block, dispose in case of any exception: 您应该将它存储到本地变量,并在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;
}

Try to never leave the disposable object vulnerable to exceptions, when Dispose wouldn't be called 当不调用Dispose时,尽量不要让一次性对象容易受到异常的影响

PS: someone previously mentioned to dispose inside the finally - this is obviously wrong - in non-exception path you don't want to call Dispose PS:有人先前提到过最终处理 - 这显然是错误的 - 在非异常路径中你不想调用Dispose

I would recommend that you suppress the CA2000 warning on each individual factory method, or perhaps on the entire class that contains them (but only if that is the only function of that class). 我建议您在每个单独的工厂方法上抑制CA2000警告,或者可能在包含它们的整个类上抑制CA2000警告(但仅当它是该类的唯一函数时)。

I further recommend that you include a justification: 我进一步建议你包括一个理由:

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

You're getting the error because the creator of the disposable object isn't managing it. 您收到错误是因为一次性对象的创建者没有管理它。 However, there's nothing fundamentally wrong with the design. 但是,设计没有任何根本性的错误。 You are just relying on the consumers to leverage using . 你只是依靠消费者利用using Not much different than the current ADO objects for example. 例如,与当前的ADO对象没有太大的不同。

Another alternative is to change your factory method into a "configuration" method and to put the responsibility of creating the disposable object onto the client. 另一种方法是将工厂方法更改为“配置”方法,并将创建一次性对象的责任放在客户端上。 Example: 例:

public void SetupDisosableThing(IDisposable foo)
{
 foo.Bar = "baz";
}

void Main()
{
  using (var x = new Thing())
  {
   SetupDisposableThing(x);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM