辛格尔顿与终结,但没有了IDisposable格尔、但没、IDisposable

2023-09-04 02:35:08 作者:飞天猪绿茵

这就是我通过C#CLR都懂了IDisposable和终结的,有效的C#和其他资源:

This is what I understand about IDisposable and finalizers from "CLR via C#", "Effective C#" and other resources:

IDisposable的是清理托管和非托管资源。 中的类负责非托管资源(如文件句柄)应该实现IDisposable,并提供一个终结,以保证他们正在清理,即使客户端code不上的情况下调用Dispose()。 类是负责管理资源,只有永远不应该执行终结。 如果你有一个终结,那么你必须实现IDisposable(这允许客户端code做正确的事,并调用Dispose(),而终结prevents泄漏资源,如果他们忘记了)。

虽然我理解的理由并同意所有上述情况,有一个场景,我觉得很有道理,打破这些规则:一个单身类,负责非托管资源(例如提供单点访问对特定的文件)。

While I understand the reasoning for and agree with all of the above, there is one scenario where I think it makes sense to break these rules: a singleton class that is responsible for unmanaged resources (such as providing a single point of access to particular files).

我相信它始终是错误的有一个单一个Dispose()方法,因为单实例应该活在应用程序的生命,如果任何客户端code调用Dispose(),那么你都塞。但是,你想有一个终结,以便应用程序卸载时终结​​可以清理非托管资源。

I believe it is always wrong to have a Dispose() method on a singleton because the singleton instance should live for the life of the application and if any client code calls Dispose() then you are stuffed. However, you want a finalizer so that when the application is unloaded the finalizer can clean up the unmanaged resources.

因此​​,有一个单独的类与不实现IDisposable在我看来是一个合理的事情,但这种类型的设计是违背我的理解是最佳做法的终结。

So having a singleton class with a finalizer that does not implement IDisposable seems to me to be a reasonable thing to do, yet this type of design is counter to what I understand are best practices.

这是一个合理的方法?如果不是,为什么不,什么是优越的替代品?

Is this a reasonable approach? If not, why not and what are the superior alternatives?

推荐答案

如果非托管资源被释放只在应用程序退出,你甚至都不需要担心了,因为终结过程中卸载应该处理这个对你啦。

If the unmanaged resource is released only on application exit you don't even need to worry with a finalizer since the process unload should deal with this for you anyway.

如果您有多个应用程序域,并要处理的应用程序域卸载这是一个可能的问题,但可能是一个你不必在意。

If you have multiple app domains and you want to deal with an app domain unload that's one possible issue but possibly one you don't need to care about.

我第二次的说,这样的设计可能是不正确的事情(而且将使其难以修复,随后你会发现,你实际上需要两个实例) 在您的入口点创建的对象(或延迟加载包装对象),并通过code到需要的地方使传递明确谁负责提供给谁,那么你可以自由地决定改变只使用一个几乎没有影响的code中的其余部分(它使用它被赋予)

I second those saying that this design is possibly not the right thing to do (and will make it harder to fix is subsequently you find that you do actually need two instances) Create the object (or a lazy loading wrapper object) in your entry point and pass it through the code to where it is needed making it clear who is responsible for providing it to whom, then you are free to change the decision to use only one with little effect to the rest of the code (which uses what it gets given)