我该如何确保处理可能的一次性物品?

Jør*_*ode 6 .net c# idisposable interface

我正在开发一个.NET项目,它需要与一些用户定义的类进行交互 - 称为"作业".所有作业类必须IJob按顺序实现特定接口,以便库使用它们.有时,作业类可能包含非托管资源,需要明确处理.

如果我事先不知道工作是否需要明确处理,我应该如何确保所有工作在使用后妥善处理?我自己有一些想法,但是想听听你的意见/建议:

  1. Make IJob : IDisposable,强制所有作业实现一个Dispose()方法.这将让我在从事的工作using块,但是因为大多数的工作都没有预计需要明确的处置,这可能会增加对客户端开发人员不需要的混乱.

  2. 完成涉及try-finally块中作业的所有工作,并用于finally确保Dispose()在作业实现时调用IDisposable.这使得客户端更容易实现新的作业类 - 不必实现空Dispose()方法 - 但它也隐藏了库知道并关心可支配作业的事实.

写完这篇文章之后,我倾向于倾向于解决方案#1,但我仍然认为看到替代解决方案会很好,并且我已经想到了两个方面的其他优点/缺点.

Hen*_*man 8

有一个先例:Stream基类是IDisposable nad因此所有Streams后代都是.但是MemoryStream不需要Disposing.
但是不要以try/finally为目标,using() { }块是一种更方便的速记.

所以你的选择是:你想要所有的工作都是IDisposable还是只有一些?

第一个选项产生很小的开销,第二个选项使得在必要时更容易忘记Dispose(using).


Bry*_*tts 5

#2是foreach构造的工作原理.这也是Autofac集装箱处理的工作原理.

语义上的区别在于你是否说一个工作本身一次性的,或者一个实现是否是一次性的.

从你的例子可以清楚地看出,前者不是真的,工作本身并不是一次性的.因此,我建议#2,但使用扩展方法来集中try/finally:

public static void Execute(this IJob job)
{
    try
    {
        job.Run();
    }
    finally
    {
        var disposableJob = job as IDisposable;

        if(disposableJob != null)
        {
            disposableJob.Dispose();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)