Lambda表达式

时间:2010-09-26 11:26:01

标签: lambda

除了try / catch

之外,还有更好的方法可以避免NullRefenrenceException

x => x.Child.GChild.GChildProp1

如果Child或GChild恰好为null,则会引发NullRefenrenceException

弹出头部的其他解决方案是从左侧单独评估每个表达式部分?

哪个更好还是有更好的解决方案?

4 个答案:

答案 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; };

祝你好运, 基督教