【发布时间】:2016-05-05 19:59:54
【问题描述】:
elvis 运算符,又名空条件运算符,非常酷。
在 LINQ 查询中,它与 null-coalescing "??" 配合使用效果很好。运算符。
Somedata.Where(dt=>(dt?.Inner?.InnerMost?.Include=="Yes")??false);
但是如果你需要转换中间值怎么办?
对于链条中的一个环节,效果很好。
Somedata.Where(dt=>(
((InnerClass)dt?.Inner)
?.InnerMost)?.Include=="Yes")
??false);
但如果有额外的必要强制转换,则强制转换和调用会“分开”。
Somedata.Where(dt=>(
((InnerMostClass) <=== Cast
((InnerClass)dt?.Inner)
?.InnerMost)?.Include=="Yes")) <=== Use
??false);
可能在这里不止一次地弄乱了括号,但我希望你明白这一点。
虽然这个“trainwreck”调用链是一种代码味道,但有没有一种更具表现力的方式来提高简洁性和清晰度?
【问题讨论】:
-
这可能看起来好一点
((((dt as InnerClass)?.Inner) as InnerMostClass)?.InnerMost)?.Include=="Yes")) ?? false -
我想不出比@Andrey 解决方案更好的方法了,当然,首先不要写这些类型的语句。尝试将尽可能多的功能压缩到尽可能少的行中很有趣,但是有代码高尔夫。对于人们需要维护的代码,我的经验是,如果你不能一眼看出 lambda 在做什么,它应该是一个命名函数......不过是个好问题......
-
我支持 pseudoDust:我会放弃那句话。你必须花费大量的脑力来弄清楚它在做什么是一种代码味道。另外,我会担心我发现自己处于什么情况下,我不得不强制转换父母及其子女,其中任何一个都可能是空的。
-
我无法理解与 LINQ 相关的问题。整件事对我来说看起来很奇怪。它确实有味道,但我认为 LINQ 或空条件运算符没有问题。我可以用
Cast<T>()或OfType<T>()来美化它,但我不知道它是否会更好。 -
你可以写一个扩展方法
SelectCast<T>,它会做Select(dt=>dt.Inner as T).Where(x=>x!=null)。然后你可以链接它们Somedata.SelectEx<InnerMostClass>(dt=>dt.Inner).SelectEx<InnerMost>(x=>x.Inner)等等......好吧,实际上你需要其中的几个方法......我想这不值得:)
标签: c# linq c#-6.0 null-coalescing-operator null-conditional-operator