CA2000 / CA2202 for using using using语句

时间:2014-02-19 17:07:38

标签: c# stream dispose ca2000 ca2202

CA2000和CA2202警告最近一直是我存在的祸根。我在这做错了什么?我基本上使用FileStream获得File.Open,然后将其传递给可能返回新流或可能返回相同流的函数。然后我在我的流上执行了一些更多的操作,然后在我的finally块中,我处理了我正在使用的流,如果它不同的话。

我收到两个CA警告。 2000 fileStream块中的usingchangedStream块中finally的220 {是什么给了什么?

using (Stream fileStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    Stream changedStream = null;
    try
    {
        changedStream = someCondition ? fileStream : DoSomeActionThatMayReturnNewStream(fileStream);
        DoSomeMoreStuffWithStream(changedStream);
    }
    finally
    {
        if (changedStream != null && changedStream != fileStream)
        {
            changedStream.Dispose();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

在什么情况下,如果有,DoSomeActionThatMayReturnNewStream会处理传入的流吗?如果它在创建新流时处理传入的流(通常是预期的),Dispose块触发的using将是多余的。

如果DoSomeActionThatMayReturnNewStream永远不会处理传入的流,似乎代码的行为可能是正确的,但FxCop无法分析其复杂和非正统的对象所有权模式。我建议做一些像

这样的事情会更好
Stream inputFile = null;
try
{
  inputFile = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  DoSomeActionThatMayReturnNewStream(ref inputFile);
  DoSomeMoreStuffWithStream(inputFile);
}
finally
{
  if (inputFile != null)
    inputFile.Dispose();
}

如果要打开一个新流,DoSomeActionThatMayReturnNewStream应该处理旧流。它应该在关闭旧流之前立即使变量为空,并在打开新流时立即分配它。这将确保如果在方法期间发生异常,那么旧流将被处置,当且仅当它之前没有处理过,并且如果其构造函数完成,新流将被处置,即使DoSomeActionThatMayReturnNewStream之后引发异常[如果该方法在新流上调用Dispose以防异常被抛出,则在这种情况下它应该使变量为空]。

答案 1 :(得分:0)

以下内容有什么问题:

using (var fileStream = System.IO.File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    using (var changedStream = someCondition ? fileStream : DoSomeActionThatMayReturnNewStream(fileStream))
    {
        DoSomeMoreStuffWithStream(changedStream);
    }
}