我假设,看起来,当没有找到结果时问题又SelectNodes
回来了。null
这是我经常遇到的一种模式:一系列操作,其中一些可以返回null
值,其中 any 的null
产生应该导致整个序列产生null
.
一种解决方案是使用函数式程序员所称的Maybe
monadBind
方法:
public static U IfNotNull<T, U>(this T self, Func<T, U> func)
where U : class
{
return (self != null) ? func(self) : null;
}
这将“传播”空值而不是抛出异常。然后,
doc.DocumentNode
.SelectNodes("//body[@id='person']")
.IfNotNull(nodes => nodes.Select(p => p.InnerText));
如果SelectNodes
返回IEnumerable<XmlNode>
,您可以使用Enumerable.Empty<>
:
(doc.DocumentNode.SelectNodes("//body[@id='person']") ?? Enumerable.Empty<XmlNode>())
.Select(p => p.InnerText);
或者,为了更好的可读性,编写一个扩展方法以避免担心运算符语法:
public static T Coalesce<T>(this T self, T other)
where T : class
{
return self ?? other;
}
和:
doc.DocumentNode.SelectNodes("//body[@id='person']")
.Coalesce(Enumerable.Empty<XmlNode>())
.Select(p => p.InnerText);
这些都是推迟空检查的各种方法,直到您准备好处理结果,而不必捕获NullPointerException
s(或ArgumentException
s 在扩展方法的情况下)。请注意,如果您在最后抛出一个简单的运算符,则任何产生null
值的方法都可能产生默认值??
。