【问题标题】:Is there a way to Imitate C# 6 Null-Conditional operator in C# 5有没有办法在 C# 5 中模仿 C# 6 空条件运算符
【发布时间】:2016-03-05 19:22:39
【问题描述】:

我有一种情况,我需要在对象初始化器中分配一些对象的属性。其中一些对象可以为空,我需要访问它们的属性,问题是它们太多了,使用 if/else 的东西不好。

示例

visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
{
    VisiteId = joined.Visite.VisiteId.ToString(),
    NomPointDeVente = joined.VisitePdvProduit.PointDeVente.NomPointDeVente,             
});

joined.VisitePdvProduit 可以为空,问题是这样的赋值有几十个(我只取了一个来缩短代码)

C# 6Null-Conditional operator是这种情况的完美解决方案,问题是我在这个项目中使用C# 5,有没有办法模仿?

【问题讨论】:

  • 创建扩展方法
  • visitJoins.AsEnumerable().Where(vj => vj.VisitePdvProduit != null).Select(joined => new VisitPDV()怎么样
  • @ClayVerValen 正如我所说的我有多个这样的任务,我只是缩短了它以避免这里出现长代码,做你的建议不会有帮助。

标签: c# .net c#-5.0 c#-6.0


【解决方案1】:

像这样。丑陋,但必须做什么。

 visits = visitJoins.AsEnumerable().Select(joined => new VisitPDV()
 {
     VisiteId = joined.Visite.VisiteId.ToString(),
     NomPointDeVente = (joined.VisitePdvProduit == null) ? null : joined.VisitePdvProduit.PointDeVente.NomPointDeVente,             
 });

【讨论】:

  • 不值得一票否决,不知道为什么,确实如你所说,它有点难看,但它确实有效,而且可以理解,赞成。
【解决方案2】:

如果你说的是半-非常惊讶操作符?.,那么不是。无法模仿语法。

不过,您可以做的是创建一个扩展方法(或辅助方法,最好是静态方法)或使用属性的实例方法。

或者,正如有人建议的那样,只需使用条件语句(内联或显式)。但这当然不是您想要的。

另一种方法(它根本不推荐推荐)是用try-catch包围分配。但那是真正的 baaad 解决方案,我只是为了完整起见而提及它。

【讨论】:

  • “非常惊讶的操作员”?是错字吗?
  • @NickWhaley 抱歉,按键太快了。更正了答案。
  • @Amy 是的,错字。我纠正了正确的。答案是一样的。我只是输入错误(并称之为半错误,teehee)。
  • 我也听说过它叫猫王算子。
【解决方案3】:

好吧,您可以使用一个扩展方法来接收访问器委托,并且仅当项目不是 null 时才执行它:

public static TResult ConditionalAccess<TItem, TResult>(this TItem item, Func<TItem, TResult> accessor) where TResult : Class
{
    if (item == null)
    {
        return null;
    }
    else
    {
        return accessor(item);
    }
}

你可以像这样使用它:

NomPointDeVente = joined.VisitePdvProduit.ConditionalAccess(_ => _.PointDeVente.NomPointDeVente);

您可以轻松地为不返回值(即bar.ConditionalAccess(_ =&gt; _.Foo()))或不返回值类型的操作创建此方法的版本。

【讨论】:

  • 这仅适用于顶级属性扩展。
  • 为什么TResult 必须是一个类?如果您处理的是Nullable&lt;T&gt;,它是struct,该怎么办?
  • @i3arnon,您必须在每个级别的属性扩展上调用它。
  • @juharr 您需要对返回值类型进行特殊处理,因为委托需要使用TResult 进行编译,但返回值需要为Nullable&lt;TResult&gt;
  • @Amy 当然.. 但它适用于每个级别。正如您需要为每个条件访问使用?.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 2016-04-01
相关资源
最近更新 更多