拉姆达表达式

发布于 2024-09-25 03:08:48 字数 257 浏览 3 评论 0原文

除了 try/catch 之外,是否有更好的方法来避免 NullRefenrenceException

x => x.Child.GChild.GChildProp1

如果 Child 或 GChild 恰好为 null 显然这会引发 NullRefenrenceException

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

哪个会更好或者有更好的解决方案?

Is there a better way to avoid NullRefenrenceException other than try/catch

i.e

x => x.Child.GChild.GChildProp1

If Child Or GChild happen to be null obviously this would raise NullRefenrenceException

other solution that popped into the head, is to evaluate each expression part individually from left ?

which would be better or it there a better solution ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

囍笑 2024-10-02 03:08:48

好吧,您可以将其转换为表达式树而不是委托,并仔细导航它。但不,C# 没有“空安全解引用运算符”之类的东西。我认为 C# 团队已经对此进行了调查,发现很难想出一些能够真正按照您自然希望的方式工作的东西。当然,这并不是说他们以后不会再考虑:)

(这听起来确实是一个相对容易实现的语言功能......但当他们说时,我相信团队存在隐藏的复杂性!)

我真的不想捕获 NullReferenceException 作为解决这个问题的方法...我更喜欢编写一个方法来针对特定情况显式检查空引用。不过这取决于你的情况。

Well, you could convert that into an expression tree instead of into a delegate, and carefully navigate it. But no, C# doesn't have anything like a "null-safe dereferencing operator". I gather the C# team has looked into it, and found it hard to come up with something which actually works the way you'd naturally want it to. That's not to say they won't have another look at a later date, of course :)

(It certainly sounds like a relatively easy language feature to implement... but I trust the team when they say there are hidden complexities!)

I wouldn't really want to catch a NullReferenceException as a way round this though... I'd prefer to write a method which checked for null references explicitly for the particular case. It depends on your situation though.

兔小萌 2024-10-02 03:08:48

嗯,这有什么根本性的错误吗?

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;

请注意,对层次结构中的第三个属性没有进行空检查,因为我认为可以选择那些空的属性。

我之所以把它扔在那里,是因为 Jon 的答案让我感兴趣,我希望他解释更多有关将其更改为表达式树的信息 - 主要是因为我不喜欢在 linq 表达式中间弹出一个单独的函数,除非我确实必须(只是个人喜好,其他人可能有不同的意见:)

Hmmm, is there anything fundamentally wrong with this?

myList.Where(x => x.Child != null && x.Child.GChild != null).Select(x => x.Child.GChild.GChildProp1);

or:

var z = from x in myList
        where x.Child != null && x.Child.GChild != null
        select x.Child.GChild.GChildProp1;

Note there was no null check on the third property in the heirarchy as i presume it is okay to select those that are null.

I'm mainly throwing this out there because Jon's answer interests me and i want him to explain more about changing this to an expression tree - mainly because i don't like popping out to a separate function in the middle of a linq expression unless i really have to (just personal preference, others may have a different opinion :)

时光病人 2024-10-02 03:08:48

仅应在特殊情况下抛出异常,即在您无法解释的情况下(即内存不足等)。对于上述情况使用 try/catch 被认为是不好的做法(出于性能和可调试性原因等),可以通过检查空引用来避免,即

x => { if (x.Child != null && x.Child.GChild != null) x.Child.GChild.GChildProp1; };

最好的问候,
基督教

Exceptions should only be thrown in exceptional cases i.e. in cases you can't possibly account for (i.e. out of memory etc.). Using try/catch for cases like above is considered bad practice (for performance and degbuggability reason etc) and can be avoided by checking for null references i.e.

x => { if (x.Child != null && x.Child.GChild != null) x.Child.GChild.GChildProp1; };

Best regards,
Christian

幸福丶如此 2024-10-02 03:08:48

如果您想要单个表达式,您可以使用可以处理空引用而不会引起异常的通用方法:

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);

如果您在途中获得空引用,则最终会得到最终属性的默认值(如果它是引用类型,则为 null)。

If you want a single expression, you could use a generic method that can handle null references without causing an exception:

public static R TryGet<T,R>(T obj, Func<T,R> getProperty) {
  if (obj == null) {
    return default(R);
  } else {
    return getProperty(obj);
  }
}

Now you can use that to try to get a property:

x => TryGet(TryGet(TryGet(x, y => y.Child), y => y.GChild), y => y.GChildProp1);

If you get a null reference on the way, you end up with the default value of the final property (which is null if it's a reference type).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文