どうやら、結果が見つからないときに問題がSelectNodes
再発していると思います。null
これは私が頻繁に遭遇するパターンです: 一連の操作で、そのうちのいくつかはnull
値を返す可能性があり、いずれかnull
を生成するとシーケンス全体がnull
.
Maybe
1 つの解決策は、関数型プログラマーがモナドのBind
メソッドと呼ぶものを使用することです。
public static U IfNotNull<T, U>(this T self, Func<T, U> func)
where U : class
{
return (self != null) ? func(self) : null;
}
これは、例外をスローするのではなく、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 チェックを延期するさまざまな方法です。最後に単純な演算子を投げると、値を生成するこれらのいずれかがnull
代わりにデフォルト値を生成する可能性があることに注意してください。??