如果静态类具有任何IDisposable静态变量,则该类是否应具有“静态析构函数”来处理它们?例如:
public static StaticClass
{
static SomeDisposableType
someDisposable = new SomeDisposableType();
static readonly StaticDestructor
staticDestructor = new StaticDestructor();
private sealed class StaticDestructor
{
~StaticDestructor()
{
someDisposable.Dispose();
}
}
}
不,不应该。
运行时无法知道何时,您的静态类将在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破坏您的进程时不会清除/释放。虽然这是事实,但这些外部资源必须应付您的进程被用户终止,或者由于电源故障(如果不在同一台机器上位于同一台机器上)而终止了整个机器。断电时,您无需运行任何清理代码。因此,必须对它们进行编码,以处理无法释放资源的过程。
这里有一些代码气味。
这将阻止StaticClass进行完全的单元测试。例如,如果不同时测试SomeDisposableType的行为,就不能测试StaticClass的行为。
我几乎总是建议您将StaticClass设为非静态,并使用构造函数注入将其依赖的服务作为接口注入,允许依赖注入框架的配置确定这些对象的生存期。
如果没有令人信服的理由让StaticClass为单例,那么就让它为瞬态。您的DI框架应注意清理注入其中的一次性物品。
如果有一个令人信服的理由让StaticClass成为一个单例,请认真思考一下您的关注点分离:StaticClass做得太多吗?例如,也许正在做一些工作来查找值,然后存储这些值以避免以后再做该工作。也许是保存应用程序某些属性的状态,并根据该状态进行操作。在这些情况下,通常可以将状态保存或备忘录/缓存工作分开在单独的类中,该类可以是单例绑定的。然后,使用此状态或缓存值的服务仍可以是瞬态的,并且在完成特定工作后仍可以处置其可抛弃的依赖项。如果考虑了以上所有因素,但您仍然确信此类需要较长的生存期,则应仔细考虑一次性依赖的生存期。通常,如果一个类是一次性的,那是因为它保留了应不时释放的资源。在这种情况下,您应该注入一个工厂,您可以使用该工厂按需构造服务,然后在通过 很难在不了解您的特定班级的情况下提出更具体的建议,但是这些是我发现在大多数情况下最有效的模式。using
语句完成操作后立即将其处置,而不是直接注入该类。