dlf
dlf

Reputation: 9393

Exception filter triggers CA2202?

I have a function that, boiled down, looks like this:

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

Under Visual Studio 2015, this generates code analysis warning CA2202:

Object 'root2.Elements().GetEnumerator()' can be disposed more than once in method 'XmlProcessor.Merge(string, string)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.

If I remove the when clause, the warning goes away.

What's going on here? Is it right to be warning me?

For reference:

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

Upvotes: 3

Views: 245

Answers (1)

NikolaiDante
NikolaiDante

Reputation: 18649

I think this is an issue with Code Analysis and I would suppress it. If I convert the loop from:

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

to this to expose the enumerator it's complaining about explicitly:

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

Then CA2202 isn't thrown anymore, even with the when filer on the exception.

Upvotes: 1

Related Questions