XDocument.Root:可能的System.NullReferenceException

时间:2016-10-24 16:29:36

标签: c# linq-to-xml resharper

看起来R#在以下代码中检测到可能的空引用:

var importedDoc = XDocument.Parse(importedXml);
var importedElements = importedDoc.Root.Elements().ToList();

访问importedDoc.Root财产时。尴尬的是,现在我想对我的方法进行单元测试,但是我无法通过importedXml,因此生成的XDocument.Root会抛出NullReferenceException。我已经添加了空检查代码来抛出异常,如果是这种情况我想覆盖那个分支:

if (importedDoc.Root == null)
    throw new NullReferenceException("There is no root element");

任何人都可以提供一种方法来实现这一点,或者,如果没有,至少可以解释R#如何提出此代码警告? Root属性是否未标记为 [NotNull] ,因为构建XDocument实际上Root的{​​{1}}可能有不同的方式?如果是这样,这不是null中的错误吗?

2 个答案:

答案 0 :(得分:2)

resharper不知道任何类型的运行时检查XDocument.Parse可能会也可能不会确保存在根级别元素。它只是将XDocument.Parse视为可能返回null的函数的调用,并建议您应该测试实际使用返回对象成员的空条件。

因为importedDoc.Root实际上不能为空,因为在这种情况下执行解析时XDocument.Parse会抛出,你可以用注释关闭resharper警告

// ReSharper disable once PossibleNullReferenceException
var importedElements = importedDoc.Root.Elements().ToList();

或者您可以自己添加空检查并重新引发异常,如果您希望这样做以使resharper满意:

var importedDoc = XDocument.Parse(importedXml);
var importedElements = importedDoc?.Root?.Elements().ToList() ?? new List<XElement>();

if (importedElements.Count == 0) throw new InvalidOperationException("No root");

或者你可以完全忽略整个事情,因为知道这个特殊警告在这种情况下并不完全有效。

答案 1 :(得分:0)

您收到此警告的具体原因是R#的XDocument.Root外部注释表示它可以为空。 R#s external annotations are open-sourced,因此您可以自己查看该项目here on github(撰写本文时的第214行)。

现在,在这个特定的代码路径中(通过XDocument创建Parse),对反编译代码的检查显示Root 在这种情况下永远不会是null,因为XDocument.Load如果在加载完成后发现Rootnull,则会抛出;但这并不是说Root永远不会 null。因此,一次性R#警告抑制似乎是最合适的。