静态类应将其IDisposable变量处置在“静态析构函数”中吗?

问题描述 投票:2回答:2

如果静态类具有任何IDisposable静态变量,则该类是否应具有“静态析构函数”来处理它们?例如:

public static StaticClass
{
    static SomeDisposableType
        someDisposable = new SomeDisposableType();

    static readonly StaticDestructor
        staticDestructor = new StaticDestructor();

    private sealed class StaticDestructor
    {
        ~StaticDestructor()
        {
            someDisposable.Dispose();
        }
    }
}
c# .net dispose idisposable
2个回答
2
投票

不,不应该。

运行时无法知道何时,您的静态类将在last时间内使用。它不可能知道尽早调用清理。

因此,执行清除的唯一“明智”时间是整个过程即将终止时。但这也不是清理的正确时机。对于类似的,不受管理的内容,请接受,请阅读Raymond Chen的When DLL_PROCESS_DETACH tells you that the process is exiting, your best bet is just to return without doing anything

建筑物正在拆除。不要打扫地板,倒空垃圾桶和擦除白板。

现在,有些人可能会提出这样的论点,即您的一些可弃置物可能代表external资源,这些资源在OS破坏您的进程时不会清除/释放。虽然这是事实,但这些外部资源必须应付您的进程被用户终止,或者由于电源故障(如果不在同一台机器上位于同一台机器上)而终止了整个机器。断电时,您无需运行任何清理代码。因此,必须对它们进行编码,以处理无法释放资源的过程。


1
投票

这里有一些代码气味。

  1. StaticClass与它所依赖的特定类型紧密相连,而不仅仅是它们的接口。
  2. StaticClass确定其使用的服务的生存期。

这将阻止StaticClass进行完全的单元测试。例如,如果不同时测试SomeDisposableType的行为,就不能测试StaticClass的行为。

我几乎总是建议您将StaticClass设为非静态,并使用构造函数注入将其依赖的服务作为接口注入,允许依赖注入框架的配置确定这些对象的生存期。

如果没有令人信服的理由让StaticClass为单例,那么就让它为瞬态。您的DI框架应注意清理注入其中的一次性物品。

如果有一个令人信服的理由让StaticClass成为一个单例,请认真思考一下您的关注点分离:StaticClass做得太多吗?例如,也许正在做一些工作来查找值,然后存储这些值以避免以后再做该工作。也许是保存应用程序某些属性的状态,并根据该状态进行操作。在这些情况下,通常可以将状态保存或备忘录/缓存工作分开在单独的类中,该类可以是单例绑定的。然后,使用此状态或缓存值的服务仍可以是瞬态的,并且在完成特定工作后仍可以处置其可抛弃的依赖项。如果考虑了以上所有因素,但您仍然确信此类需要较长的生存期,则应仔细考虑一次性依赖的生存期。通常,如果一个类是一次性的,那是因为它保留了应不时释放的资源。在这种情况下,您应该注入一个工厂,您可以使用该工厂按需构造服务,然后在通过using语句完成操作后立即将其处置,而不是直接注入该类。

很难在不了解您的特定班级的情况下提出更具体的建议,但是这些是我发现在大多数情况下最有效的模式。

© www.soinside.com 2019 - 2024. All rights reserved.