【问题标题】:Elvis operator in a casting invocation chain铸造调用链中的 Elvis 运算符
【发布时间】: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&lt;T&gt;()OfType&lt;T&gt;() 来美化它,但我不知道它是否会更好。
  • 你可以写一个扩展方法SelectCast&lt;T&gt;,它会做Select(dt=&gt;dt.Inner as T).Where(x=&gt;x!=null)。然后你可以链接它们Somedata.SelectEx&lt;InnerMostClass&gt;(dt=&gt;dt.Inner).SelectEx&lt;InnerMost&gt;(x=&gt;x.Inner) 等等......好吧,实际上你需要其中的几个方法......我想这不值得:)

标签: c# linq c#-6.0 null-coalescing-operator null-conditional-operator


【解决方案1】:

您可以通过使用非常简单的扩展方法来保持链接并防止括号:

dt?.Inner.As<InnerClass>()?.InnerMost.As<InnerMostClass>()?.Include == "Yes"

扩展方法定义如下:

public static class ObjectExtensions
{
    public static T As<T>(this object obj) where T : class
    {
        return obj as T;
    }
}

【讨论】:

  • 有趣。太糟糕了,我们需要在那里使用“object”和“:class”约束。如果我们可以指出 TInput 需要是 TResult 的接口或基类才能获得一些编译时检查,那将是很酷的。但是在 C# 中,这需要 TInput 和 TResult 都是显式类型参数。对我们来说,最佳状态是只声明 TResult,而让 TInput 被推断出来。我想我的未来会有 F#……除非我忘记了什么。
猜你喜欢
  • 2015-10-15
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多