除了try / catch
之外,还有更好的方法可以避免NullRefenrenceException即
x => x.Child.GChild.GChildProp1
如果Child或GChild恰好为null,则会引发NullRefenrenceException
弹出头部的其他解决方案是从左侧单独评估每个表达式部分?哪个更好还是有更好的解决方案?
答案 0 :(得分:2)
好吧,你可以将其转换为表达式树而不是委托,并仔细导航它。但不,C#没有像“空安全解除引用运算符”那样的东西。我认为C#团队已经对它进行了调查,并发现很难找到一些实际上与你自然想要的方式相同的东西。这并不是说他们不会再看看日后了,当然:)
(当然听起来就像一个相对容易实现的语言功能......但我相信团队,当他们说有隐藏的复杂性!)
我真的不想抓住NullReferenceException
来解决这个问题......我宁愿编写一个方法,针对特定情况明确检查空引用。这取决于你的情况。
答案 1 :(得分:0)
如果你想要一个表达式,你可以使用一个泛型方法来处理空引用而不会导致异常:
public static R TryGet<T,R>(T obj, Func<T,R> getProperty) {
if (obj == null) {
return default(R);
} else {
return getProperty(obj);
}
}
现在您可以使用它来尝试获取属性:
x => TryGet(TryGet(TryGet(x, y => y.Child), y => y.GChild), y => y.GChildProp1);
如果你在路上得到一个空引用,你最终会得到final属性的默认值(如果它是引用类型,则为null)。
答案 2 :(得分:0)
myList.Where(x => x.Child != null && x.Child.GChild != null).Select(x => x.Child.GChild.GChildProp1);
或:
var z = from x in myList
where x.Child != null && x.Child.GChild != null
select x.Child.GChild.GChildProp1;
注意,对于heirarchy中的第三个属性没有空检查,因为我认为可以选择那些为空的。
我主要是把它扔出去,因为Jon的回答让我很感兴趣,我希望他解释更多关于将它改为表达式树 - 主要是因为我不喜欢在linq中间弹出一个单独的函数表达除非我真的必须(只是个人偏好,其他人可能会有不同意见:)。
答案 3 :(得分:0)
例外情况只应在特殊情况下抛出,即在您无法解决的情况下(即内存不足等)。对于上述情况使用try / catch被认为是不好的做法(出于性能和可破坏性等原因),可以通过检查空引用来避免,例如
。x => { if (x.Child != null && x.Child.GChild != null) x.Child.GChild.GChildProp1; };
祝你好运, 基督教