【问题标题】:How can I assign a Func<> using the conditional ternary operator? [duplicate]如何使用条件三元运算符分配 Func<>? [复制]
【发布时间】:2014-09-04 14:12:26
【问题描述】:

更新

在 C#10 中,此语法现在有效,编译器将为 lambda Example here 推断“自然类型”

C# 9 及更早版本

我知道 Func&lt;&gt;s 不能通过 var 关键字直接隐式输入,尽管我更希望我可以对谓词进行以下分配:

Func<Something, bool> filter = (someBooleanExpressionHere)
   ? x => x.SomeProp < 5
   : x => x.SomeProp >= 5;

但是,我收到错误 cannot resolve the symbol, 'SomeProp'

目前,我使用了更繁琐的if branch赋值,看起来并不优雅。

Func<Something, bool> filter;
if (someBooleanExpressionHere)
{
    filter = x => x.SomeProp < 5;
}
else
{
    filter = x => x.SomeProp >= 5;
}

我是否遗漏了什么,或者我需要坚持 if-branch 分配?

【问题讨论】:

  • 你试过在不同的地方添加括号吗?例如(x =&gt; x.SomeProp &lt; 5)
  • 编译器可能不知道 lambda 变量 x 是什么类型。为什么不将这两个表达式放在单独的变量中,然后使用三元运算符将其中一个分配给过滤器变量?
  • @AlexMDC:做到了。没用。

标签: c# lambda func


【解决方案1】:
var filter = (someBooleanExpressionHere)
   ? new Func<Something, bool>(x => x.SomeProp < 5)
   : x => x.SomeProp >= 5;

【讨论】:

  • 谢谢 - 我可以使用 var - 有点 - 奖金 :) !
  • @StuartLC 你可以使用var,但如果没有明确输入类型名称,你实际上并没有var的好处。实际上,我想说有相当数量的人会认为你原来的if/else 比这更优雅。 (就个人而言,我是分裂的。我对其中一个没有真正的偏好。)
  • 是的,因此是“种类”。但至少我不必拼出我的 lambda 签名 两次
  • 为了进一步解释为什么需要这样做,C# 中的 lambdas 本身没有类型,lambda 的类型是从用法中推断出来的。在三元条件表达式的情况下,编译器无法推断 lambda 类型,因为它需要知道这一点才能推断条件表达式的类型。显式实例化 Func 允许编译器找出表达式类型,并从中推断出另一个 lambda 的类型也是 Func
【解决方案2】:

您应该将它们包装在 new Func 中,否则它无法将一个 lamdba 转换为另一个:

 Func<Something, bool> filter = (someBooleanExpressionHere)
   ? new Func<Something, bool>(x => x.SomeProp < 5)
   : x => x.SomeProp >= 5
   ;

如果您删除new Func...,您将获得:

无法确定条件表达式的类型,因为“lambda 表达式”和“lambda 表达式”之间没有隐式转换

【讨论】:

  • 第二个操作数上的括号并不是绝对必要的,尽管我同意它们值得添加。不是每个人都记得所有的优先规则,所以它提高了可读性。
  • 没错,我首先尝试了两个new Func,但最后一个没有必要。
【解决方案3】:

您可以明确提及类型作为编译器的提示

var filter = (condition)
    ? (Func<Something, bool>)(x => x.SomeProp < 5)
   : x => x.SomeProp >= 5;

【讨论】:

    【解决方案4】:

    如果合适,您可以将这些选择器分配给静态字段。

    private static readonly Func<Something, bool> _someFilter = x => x.SomeProp < 5;
    private static readonly Func<Something, bool> _someOtherFilter = x => x.SomeProp >= 5;
    

    您以后可以使用它们。

    var filter = (someBooleanExpressionHere) ? _someFilter : _someOtherFilter;
    

    【讨论】:

      猜你喜欢
      • 2010-09-20
      • 2010-09-28
      • 2012-07-03
      相关资源
      最近更新 更多