【问题标题】:C# lambda unnamed parametersC# lambda 未命名参数
【发布时间】:2012-12-10 07:50:04
【问题描述】:

是否有可能通过不给它们命名来丢弃 lambda 表达式中的一些参数? 例如。我必须传递一个 Action,但我只对第二个参数感兴趣,我想写类似的东西

(_, foo) => bar(foo)
// or
(, foo) => bar(foo)

在第一种情况下它正在工作。但是第一个参数并不是真正的未命名,因为它的名称为“_”。因此,当我想丢弃两个或更多时,它不起作用。我选择 _ 因为在 prolog 中它的意思是“任何值”。

所以。我的用例是否有任何特殊字符或表达式?

【问题讨论】:

    标签: c# parameters lambda


    【解决方案1】:

    不,你不能。查看C# language specification 语法,有两种声明 lambda 的方法:显式和隐式。两者都不允许您跳过参数的标识符或重用标识符(名称)。

    explicit-anonymous-function-parameter:
      anonymous-function-parameter-modifieropt   type   identifier
    
    implicit-anonymous-function-parameter:
      identifier
    

    与普通函数中未使用的函数参数相同。必须给他们一个名字。

    当然,您可以使用_ 作为参数之一的名称,因为它是一个有效的 C# 名称,但这并不意味着任何特殊。

    从 C# 7 开始,_ 确实具有特殊含义。不适用于 lambda 表达式参数名称,但绝对适用于其他事物,例如模式匹配、解构、输出变量甚至常规赋值。 (例如,您可以使用_ = 5; 而不声明_。)

    【讨论】:

    • _ does 自 C# 7 起具有特殊含义。不适用于 lambda 表达式参数名称(据我所知),但绝对适用于其他事物,例如模式匹配、解构、out 变量甚至常规赋值。 (例如,您可以使用 _ = 5; 而不声明 _。)我意识到这个答案是在 C# 7 之前几年写的,但鉴于最后一行已经不正确,如果有时间,最好编辑一下.
    • @JonSkeet 感谢您的关注,我在编辑中添加了您的 cmets。我需要更好地预测未来。
    • 我经常处于同一个位置 - 在这种情况下,我实际上已经有一段时间没有注意到这是一个旧答案......新答案已经把这个问题放在了首页.
    • 总而言之,表达式new [] { 1, 2, 3 }.Select(_ => DoStuff(_)) 在语法上是正确的,但在语义上是错误的?我到处都看到了这一点,只是发现了丢弃模式。对我来说,不必用字符 #firstworldproblems 把一个小小的 lambda 搞得一团糟似乎很实用
    【解决方案2】:

    简短的回答是:不,您必须命名每个参数,并且名称必须是唯一的。

    您可以使用 _ 作为参数名称,因为它是 C# 中的有效标识符。
    但是,您只能使用一次。

    【讨论】:

    • 这就是为什么我经常使用(_, __, ___, foo) => { ... }
    • 请注意,lambda 函数的丢弃在此 GitHub 问题中被作为一种语言功能进行跟踪:github.com/dotnet/csharplang/issues/111
    【解决方案3】:

    现在你可以了!

    从 C# 9.0 开始,您可以使用下划线字符“丢弃”一个或多个 lambda 参数。来自Microsoft Docs

    从 C# 9.0 开始,您可以使用丢弃来指定 lambda 表达式的两个或多个未在表达式中使用的输入参数:

    Func<int, int, int> constant = (_, _) => 42;
    

    【讨论】:

      【解决方案4】:

      在 C# 7 中,您可以使用丢弃。丢弃是您无法读取的只写变量。它基本上适用于您不想使用的变量 更多详情here

      【讨论】:

      • 这是真的,其他答案都错过了,但据我所知,与 lambda 表达式参数无关。 (例如,您不能使用(_, _, x) =&gt; x。)
      • @JonSkeet 所以你不能用这个? (_, foo) => bar(foo)
      • 可以,但是_ 只是一个常规参数。您不能使用(_, _, x),因为那样您将两次声明相同的参数。 (而您可以在模式中多次使用_。)
      • @JonSkeet 好的,现在我明白了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      • 2022-01-04
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多