CA2202在示例中使流无效

时间:2018-05-31 11:17:08

标签: c#

Microsoft的文档中,给出了使用流的以下示例。

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();  
}  

现在我想知道为什么在使用编写器对象之前设置stream = null

1 个答案:

答案 0 :(得分:3)

CA2202标题为不要多次丢弃对象。我认为这是一个愚蠢的规则,因为the description of IDisposable.Dispose() 非常明确:

  

如果多次调用对象的Dispose方法,则该对象必须忽略第一个之后的所有调用。如果多次调用Dispose方法,则该对象不得抛出异常。

因此这是一个关于非问题的规则,导致代码更复杂,什么都不是! (请注意,我不是onlyonly就是这个问题。

基本信息:StreamWriter / Close()上的Dispose()课程通常为Stream(相当于Close()课程的Dispose()) ,据说它取得了基本流的所有权。

基本问题是普通代码

using (stream = new FileStream("file.txt", FileMode.OpenOrCreate))
using (StreamWriter writer = new StreamWriter(stream))
{
}

Close()加倍stream(一次来自StreamWriter,一次来自外部using),这会受到规则的束缚。

因此,如果 Dispose()未取得stream的所有权,我们希望“手动”处理StreamWriter stream

现在...... FileStream构造函数可以抛出“正常”异常(在这种情况下stream将是null,因此无需清除)或{ {1}}构造函数(在这种情况下StreamWriter将不是 - streamnull将是writer,因此null将需要处理,完成stream块。在finally构造的末尾和StreamWriter之间只能抛出异步异常,但我们会忽略它们。现在......在stream = null;构建并分配到StreamWriter后,writer可以标记为“我们不需要处理它”(因为stream将为我们关闭它,所以StreamWriter。请注意,在stream = null;using ()之间放置其他行可能会创建引发异常的其他点,例如:

stream = null;

但这会导致using (StreamWriter writer = new StreamWriter(stream)) { if (something) throw new Exception(); stream = null; // Use the writer object... } 上的Dispose()加倍。{/ p>