请考虑以下代码:
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
// Use the writer object...
}
}
当writer
流被处置时,它会在内部处理FileStream stream
。
除了MSDN recommendation以外,还有其他设计可以在finally子句中处理外部使用的流:
Stream stream = null;
try
{
stream = new FileStream("file.txt", FileMode.OpenOrCreate);
using (StreamWriter writer = new StreamWriter(stream))
{
stream = null;
// Use the writer object...
}
}
finally
{
if(stream != null)
stream.Dispose();
}
答案 0 :(得分:3)
此特定情况的解决方案是致电the overload of the StreamWriter constructor that lets you tell it not to dispose the underlying stream。
不幸的是,这仅适用于.Net 4.5;否则你将不得不做你正在做的事情。
另外,请参阅此主题:Is there any way to close a StreamWriter without closing its BaseStream?
顺便提一下,OP中的代码 NOT 会在我尝试时导致异常!
以下示例假设存在名为“C:\ TEST”的文件夹:
using System;
using System.IO;
namespace Demo
{
public static class Program
{
public static void Main(string[] args)
{
// This does NOT cause any exceptions:
using (Stream stream = new FileStream("c:\\test\\file.txt", FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write("TEST");
}
}
}
}
}
答案 1 :(得分:3)
这种情况下,FxCop与.NET Framework中的设计选择存在很大差异。 StreamWriter假设流的所有权引起问题。这通常是“成功的陷阱”设计选择,大多数程序员都会认为关闭StreamWriter足以让流处理掉。特别是当他们使用Close()而不是Dispose()时。
在绝大多数情况下都适用。大多数情况下,一个特殊用途是非常有问题的是CryptoStream。在CryptoStream被刷新和处理之前关闭基础流时需要刷新和不可诊断故障的类。 FxCop警告适当的情况,尽管它太容易辨认特定问题太过神秘;)
一般情况下,程序员编写了自己的Dispose()方法,并且忘记了多次调用它的安全性。这就是FxCop警告引起注意的原因,它不够聪明,无法看到Dispose方法实际上是安全的。
在这种特定情况下,FxCop警告是无用的。所有.NET Framework提供的Dispose()方法实现都是安全的。 FxCop应该自动禁止.NET框架代码的这种警告。但不是,微软也使用它。 .NET框架源代码中有[strong>很多 [SuppressMessage]属性。
解决警告太丑陋且容易出错。没有意义,因为没有什么事实出错。请记住,FxCop只是一个诊断工具,旨在生成“您已考虑此”消息。当你忽视规则时,警察警察不会把你关进监狱。这是编译器的工作。
使用[SuppressMessage]属性关闭警告。