同一使用块中的多个变量
本文关键字:变量 | 更新日期: 2023-09-27 17:58:24
我目前使用两个对象,如下所示:
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
// work with ms and bw, both referenced here
}
它"很好",事实上也是一个答案。然而,当我运行VS2012的代码分析工具时,我会收到一个警告,比如:
CA2202 Do not dispose objects multiple times
Object 'ms' can be disposed more than once in method '<my method name>'.
To avoid generating a System.ObjectDisposedException you should not
call Dispose more than one time on an object.
这让我相信可能有另一种方法来处理这种情况,但我不知道它是什么
有人知道在一个using
块中以无警告的方式使用两个对象的"正确"方法是什么吗?
BinaryWriter类的编写方式是,除非使用可选的构造函数参数告诉它不要这样做,否则它将在处理BinaryWriter时处理您传递给它的基础流。由于二进制写入程序正在处理基础内存流,而您也在using
块中处理它,因此它将被处理两次。
现在,对于大多数类来说,这并不是一个真正的问题,因为它们应该(并且内存流)被写为在被丢弃两次时工作得很好,只要你在它被丢弃后不使用它(你没有),这样你就可以安全地忽略警告。如果您希望警告消失,您可以停止使用内存流,因为它已经被释放了。
如果您不需要对MemoryStream
的对象引用,这将很好地工作
using (var bw = new BinaryWriter(new MemoryStream()))
{
var memStream = bw.BaseStream as MemoryStream;
}
否则,请使用多次。特别是在使用.NET框架对象的情况下,因为它们是用正确的处置模式实现的。
当可能具有第二个dispose调用的对象没有正确实现dispose模式时,双using
语句可能会导致问题。
PS:你这样得到同样的警告吗:
using (var memStream = new MemoryStream())
{
using (var bw = new BinaryWriter(memStream))
{
// work with ms and bw
}
}
您认为这是单个使用块是不正确的。示例中的代码是嵌套使用块的语法糖,如下所示:
using (var ms = new MemoryStream())
{
using (var bw = new BinaryWriter(ms))
{
// work with ms and bw, both referenced here
}
}
没有任何一种方法可以正确地纠正这种情况并避免发出警告。在内部资源包装外部资源并且它们一起超出范围的情况下,您需要查阅文档:如果约定声明内部资源的dispose方法调用了对包装对象的dispose,那么您就不需要将外部资源放在using块中。
话虽如此,在大多数文件中可能不会提及这些细节。你可以自己检查行为(通过继承和观察副作用),但你必须小心,因为最初没有记录,这种行为可能会在未来的版本中发生变化。
因此,如果你非常担心,你可以保留双重使用块(以防万一),抑制警告,并将整个块放在try{} catch (ObjectDisposedException e) {}
中,以完全保护自己。
听起来有点偏执?取决于您使用的库:-)
我认为您不应该将"using(…){}"用于:
using (var ms = new MemoryStream())
因为操作系统管理内存并"处理"它!