ArgumentNullException未处理

时间:2012-11-07 14:57:40

标签: c# html-agility-pack

我是C#的新手。我有一个隐式的类型变量定义如下:

 var item = doc.DocumentNode.SelectNodes("//body[@id='person']")
                                  .Select(p => p.InnerText);

此var有时会返回null。这就是visual studio要求我处理ArgumentNullException的地方。但是,如果我这样做,我的var try仍然不为我所知catch - var,我就再也无法使用它了。

有人建议我使用空对象设计模式,但我不知道我应该如何为{{1}}实现它。有谁知道我应该如何处理这种情况,因为我厌倦了每次都处理空案例。

2 个答案:

答案 0 :(得分:2)

我认为,在没有找到结果的情况下,问题是SelectNodes返回null。这是我经常遇到的模式:一系列操作,其中一些操作可以返回null值,其中任何null的生成应该导致整个序列生成null。< / p>

一种解决方案是使用函数式程序员调用Maybe monad的Bind方法:

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运算符,那么产生??值的任何一个都会产生默认值。

答案 1 :(得分:0)

IEnymerable<HtmlNode> v = null;    
var item = doc.DocumentNode.SelectNodes("//body[@id='person']");
if (item != null)
{
    v = item.Select(p => p.InnerText);
}