在Using块之外访问一次性对象的未处置资源



下面的代码是完全合法的。

DisposableObject disposableObject;
...
using (disposableObject = new DisposableObject(...))
{
     disposableObject.UseDisposableResource();
}
...
var result = disposableObject.AccessUndisposedResource();

Q使用它还是保持距离?

我绝对不会这么做。通常的惯例是只在using语句的作用域中引入变量,否则会给开发人员带来困惑,而且很难发现bug。

如果开发人员希望这样做,按照约定:

using (DisposableObject disposableObject = new DisposableObject())
{
    ...
}

那么打破惯例最好的情况下会导致奇怪的代码,最坏的情况下会导致奇怪的行为/bug。

根据我的经验,using语句的典型用法与开发人员的期望非常相似(即使它是作用域更改,而不是对象的空值):

DisposableObject disposableObject = new DisposableObject();
...
disposableObject.Dispose();
disposableObject = null;

如果我照顾的开发人员做过这样的事情,我会告诉他们停止和停止!我也会改变我发现的所有实例,因为它有这样一种代码气味,而且很有可能导致难以发现/理解的bug。

这里涉及到一些规范/期望:

  1. 被处置的对象通常被认为是结束的,并且被假定在处置后不可用(尽管不是编译器强制的)
  2. using变量通常在using语句中声明,这明确地阻止了在它们被处置(同样,不是编译器强制的)时使用

你的代码违反了这两个规范——你有一个被处置的对象,它仍然是可用的,以及一个using块,它处置了一个外部变量,该变量在块之后仍然在作用域中。结果呢?混乱和难以阅读和维护的代码。

所以,是的,要避开。

我不会使用它,因为任何人阅读您的代码都会认为disposableObjectusing之后的使用是一个可用的对象

我会像其他人建议的那样,将一次性对象的范围保持在using块的范围内。

在这种情况下,using -block的用法有点误导。我个人只在块内使用disposableObject,并将AccessUndisposedResource() -逻辑拆分到其他对象。

可能是这样的:

ResultType result = null;
using (DisposableObject disposableObject = new DisposableObject(...))
{
   disposableObject.UseDisposableResource();
   ...
   result = disposableObject.AccessUndisposedResource();
}
...
// Now we can access the undisposed resource here with 'result'-variable

最新更新