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上。