避免显式调用 Dispose() 是否合理?
制定禁止在 IDisposable
对象上显式调用 Dispose()
的规则是否合理?
是否存在 using
语句无法正确确保清理 IDisposable
对象的情况?
Is it reasonable to make a rule against explicitly calling Dispose()
on an IDisposable
object?
Are there any cases where a using
statement cannot properly ensure an IDisposable
object is cleaned up?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不。
当然,在某些情况下,使用
using
来处置对象是没有意义的。例如,在所有情况下,对象的所需生存期不受包含using
语句的方法的特定激活的约束。例如,考虑一个一次性对象“接管”另一个一次性对象的管理。 “外部”对象很可能由
using
块进行处理,但是“内部”对象(可能存储在外部对象的私有字段中)如何在不显式调用 <代码>Dispose()?No.
There are certainly cases where it makes no sense to use
using
to dispose an object for you. For example, all cases where the desired lifetime of the object is not bound by a particular activation of a method containing ausing
statement.Consider for example a disposable object which "takes over management" of another disposable object. The "outer" object may well be disposed by a
using
block, but how is the "inner" object, likely stored in a private field of the outer object, to be disposed without an explicit call toDispose()
?在某些情况下,根本不可能避免显式调用
Dispose
并仍然保持正确的语义。例如,考虑具有同样为IDisposable
类型的字段的IDisposable
对象。他们必须使用显式调用Dispose
来处置该字段In some cases it's simply not possible to avoid an explicit call to
Dispose
and still maintain proper semantics. For example considerIDisposable
objects which have a field also of typeIDisposable
. They must us an explicit call toDispose
to dispose the field一个自然的假设是,您始终可以对对象调用
Dispose
,这将清理该对象的资源,无论该对象处于什么状态。这种自然的假设并不总是正确的假设。
一个示例是 WCF 客户端代理。
管理代理生命周期的正确方法如下:
切换到
using
语法将导致不安全的代码:您可能会争辩说(正如我们所有人一样)这是一个有缺陷的WCF 的设计方面,但编程的现实是,我们有时必须修改我们的样式以适应我们正在使用的框架。下面是一个示例,其中针对显式
Dispose
的一揽子规则无法应用,即使对象的生命周期包含在一个函数调用中也是如此。One natural assumption is that you can always call
Dispose
on an object, and this will clean up the object's resources, regardless of what state the object is in.This natural assumption is not always a correct assumption.
An example is with WCF client proxies..
The correct way to manage proxy lifetime is as follows:
Switching to the
using
syntax will result in unsafe code:You could argue (as we all do) that this is a flawed design aspect of WCF, but the reality of programming is that we sometimes have to modify our style to accommodate the frameworks we're using. Here's an example where a blanket rule against explicit
Dispose
cannot apply, even when the lifetime of the object is contained within one function call.using
语句(实际上是在 finally 块中调用Dispose
的 try/finally 的简写)适用于获取资源、使用它,然后用一种相同的方法处理它。如果您没有这样的资源线性使用(例如,它的使用被分散在不同的方法中),您将必须调用Dispose
。A
using
statement (which really is shorthand for a try/finally withDispose
called in the finally block) is for scenarios where you acquire a resource, make use of it, then dispose of it within one same method. If you don't have such a linear usage of the resource (e.g. its usage is split across methods) you will have to callDispose
.如果创建一次性类型实例的成本很高(例如封装远程连接的类型),您可能需要重用实例来分摊成本。在这种情况下,
using
将没有用,您必须在某个时候调用Dispose
。If the cost of creating instances of a disposable type is high (e.g. a type which encapsulates a remote connection), you may want to reuse instances to amortize the cost. In that case
using
will not be useful and you'll have to callDispose
at some point.我会投票反对这样的规则,如果你有一个对象想要在多个函数调用中多次使用,那么 using 语句将强制处置该对象,下次你想使用它时,你必须重新初始化...
I would vote against such rule, what if you have an object you want to use multiple times across several function calls, a using statement will force the disposal of that object, the next time you want to use it, you have to re-initialize...