C# 异常过滤器触发CA2202?

C# 异常过滤器触发CA2202?,c#,visual-studio-2015,compiler-warnings,code-analysis,c#-6.0,C#,Visual Studio 2015,Compiler Warnings,Code Analysis,C# 6.0,我有一个函数,归结起来如下: public static string Merge(string xml1, string xml2) { try { var doc1 = XDocument.Load(new StringReader(xml1)); var doc2 = XDocument.Load(new StringReader(xml2)); // these "die" by throwing InvalidOperationExce

我有一个函数,归结起来如下:

public static string Merge(string xml1, string xml2)
{
   try
   {
      var doc1 = XDocument.Load(new StringReader(xml1));
      var doc2 = XDocument.Load(new StringReader(xml2));

      // these "die" by throwing InvalidOperationException
      var root1 = GetElementOrDie(doc1, Names.RootElementName);
      var root2 = GetElementOrDie(doc2, Names.RootElementName);

      foreach (var element in root2.Elements())
         root1.Add(element);

      return doc1.ToString();
   }
   catch (Exception e) when (!(e is InvalidOperationException))
   {
      throw new InvalidOperationException(e.Message, e);
   }
}
在Visual Studio 2015下,这将生成代码分析警告CA2202:

对象“root2.Elements().GetEnumerator()”的释放次数可以超过 一旦进入方法“XmlProcessor.Merge(string,string)”中。避 生成不应调用的System.ObjectDisposedException 对一个对象进行多次处置

如果我删除
when
子句,警告就会消失

这是怎么回事?警告我对吗

供参考:

private static XElement GetElementOrDie(XContainer container, XName elementName)
{
   var element = container.Element(elementName);
   if (element == null)
      throw new InvalidOperationException();
   return element;
}

我认为这是代码分析的一个问题,我会抑制它。如果我将循环转换为:

foreach (var element in root2.Elements())
   root1.Add(element);
要公开它所抱怨的枚举数,请执行以下操作:

var enumerator = root2.Elements().GetEnumerator();
while (enumerator.MoveNext())
{
    XElement item = enumerator.Current;
    root1.Add(item);
}

然后不再抛出
CA2202
,即使
when
filer出现异常。

这看起来更像是代码分析的问题。我宁愿忽略这个警告。我还看到CA错误地抱怨在使用空条件运算符时没有处理对象,如
disposable?.Dispose()
我怀疑您是对的,但这一更改会停止警告也就不足为奇了,因为
Dispose
不再在枚举器上调用了。我认为要明确回答这个问题,需要检查反汇编并确认没有通过代码的路径会导致
Dispose
被多次调用。对LinqPad的快速检查显示只生成了一个调用,但我不是一个IL专家,不能确保没有任何跳转或循环会导致该指令被多次执行。也就是说,唯一的
CA2000:Dispose objects before loss scope
我在第二个版本中遇到的错误仍然在您的
StringReader
s上。