【问题标题】:C# style: Lambdas, _ => or x =>? [closed]C# 风格:Lambda、_ => 或 x =>? [关闭]
【发布时间】:2012-05-19 07:35:20
【问题描述】:

在 C# 中使用之前,我在其他语言中使用过 lambda 表达式,因此我养成了将 _ 用于 Func<T, TResult>, 形式的简单 lambda 的习惯,尤其是对于主体只是一个表示返回值的表达式(谓词等)。但是,在 C# 中,我经常看到使用单个字母而不是 _ 来表示这些相同类型的 lambda 表达式,例如 x,y,z,i,j,k。字母方法对我来说似乎很奇怪,因为这些字母在常见用法中已经具有另一个典型含义,即循环变量。在我看来,_ 通常更容易阅读。单字母样式真的是 C# 中 lambda 的既定样式吗?

例子:

我习惯写的东西:

var ages = people.Select(_ => _.Age);

我看到的是写的:

var ages = people.Select(x => x.Age); // choice of 'x' is not consistent

【问题讨论】:

  • 我从未见过使用下划线。
  • 我个人使用w 作为 lambda 参数,因为我很容易理解我在说什么。 research.microsoft.com/en-us/um/cambridge/projects/comega的残余@
  • 那只是爱简洁的人,我个人用一个有意义的名字。 x 和 _ 都没有意义。在你的例子中,年龄是我的选择。
  • 年龄对我来说没有意义,恕我直言。 “p”本来是我的选择,因为它应该代表人员集合中的一个“人”。不过,各有各的。 :)
  • @Tony 普遍认为,当范围足够小时,单字母标识符就可以了

标签: c# coding-style lambda


【解决方案1】:

许多 C# 开发人员使用_ 来表示不会使用该参数,并在使用该参数时使用字母或其他短名称​​

其他资源:

【讨论】:

  • 支持 Charlie Flowers 的文章,该文章解释了合法 _ 用法的出现。
  • 我的示例不太正确(我应该在这些示例中使用 p 或 person)。起初我认为它可能只适用于 _ 的类型是通用/未知的情况,但在所有使用 _ 的情况下,至少必须了解类型,除非您在 Object 上使用方法(在这种情况下你会使用 obj 或类似的),所以理由不成立。这让事情变得更清楚了。
  • 从未考虑将_ 用于未使用的参数。现在我可能会无处不在..
  • 这与许多函数式语言一致,其中_ 是匹配所有内容但不绑定名称的“wlidcard 模式”,例如在 Haskell 中 case 2 of x -> x2,但 case 2 of _ -> _ 是语法错误。
  • 从 C# 7 开始,_ 现在正式用作丢弃模式的一部分,类似于它在函数式语言中的使用方式。这加强了 sblom 的案例。
【解决方案2】:

没有“既定”风格来命名您的 lambda 变量。但是,下划线通常表示某种实例成员变量,这意味着与普通变量名称相比,您的样式可能与其他命名标准冲突。

长话短说 - 做对你有用的事。

【讨论】:

    【解决方案3】:

    或者您可以使用有意义的名称,例如

    var ages = people.Select(person => person.Age);
    

    【讨论】:

    • 你是对的。我的例子应该是使用人。
    【解决方案4】:

    这是一个变量名,所以我认为名称应该传达它需要传达的信息。 _ 传达了哪些信息?

    为此,x 传达了哪些信息?

    我可以这样写你的例子:

    var ages = people.Select(p => p.Age);
    

    这个想法是我觉得p 至少建议在整个声明的上下文中它是一个people 记录。你可以更进一步:

    var ages = people.Select(person => person.Age);
    

    现在 that 向读者传达了该变量实际上是什么。当然,对于这么小的声明,可以说它是矫枉过正的。我不这么认为,但这是一个偏好问题。 (不仅仅是您的偏好,还有任何必须支持此代码的人的偏好。)

    对于大得多、多行、复杂的 lambda 表达式,名称变得更加重要。离变量含义的上下文越远,变量的名称就越需要携带该上下文。

    【讨论】:

    • 当然,您正在编写 (,_)=>{notificationEventHandler();} 的丢弃参数情况(例如,对于匿名事件处理程序)是我继续看到(并支持)使用仅下划线名称的地方。
    • @TetsujinnoOni:当然。在这种情况下,变量是非变量。它需要传达的唯一信息是“我什么都不是,不要使用我。”
    • 我支持将_ => _.method() 用于单行方法调用 lambda,因为它减少了指令的认知权重。特别是在使用泛型时,写x => x.method() 只是添加了“这是什么'x'?它是空间坐标吗?”的瞬间考虑。考虑以下情况:Initialize<Client> ( _=>_.Init() ); 与泛型一起使用,这种情况下的下划线用作“绕过符号”。它避免了冗余,定义参数的类型是显而易见的并且可以从使用中推断出来——就像使用 'var' 来防止重复类型声明一样。
    【解决方案5】:

    你可以给它一个名字是有原因的——因为有时你可以有多个输入并且需要区分它们:

    Func<int,int,int> product = (num1, num2) => (num1 * num2);  // takes in two ints, and returns one int
    int x = product(2, 3);  
    

    【讨论】:

    • 是的,但我认为这不是问题所在。
    • 那你就可以成为一个真正的坏蛋了! (,) => (*);编辑:k,所以自然将我的下划线作为斜体标记。只是显示对多个输入使用双下划线(或更多)。
    • @ChrisSinclair,如果您在表达式周围加上反引号,这些特殊字符将按原样显示。
    • @MichaelKjörling 是的,几个小时后我意识到这一点,感觉就像socially awkward penguin
    【解决方案6】:

    lambda 函数与任何其他方法有何不同。如果有人要使用以下方法发布代码:

    public static int getAge(Person _)
    {
      return _.Age;
    }
    

    public static int getAge(Person x)
    {
      return x.Age;
    }
    

    你会说什么?

    在我看来,为 lambda 选择参数名称应该与任何其他方法的参数一样有意义。我可能会偶尔为标识函数 x =&gt; x 设置例外,因为在这种情况下,变量不需要表示任何含义,它实际上可以是任何东西,但是在我脑海中对所有内容使用下划线或单个字母只会使代码可读性差得多。 (很多人吹捧 LINQ/Lambdas 的优点是可读性,如果你混淆所有变量,它就会被打败。)

    【讨论】:

    • 为良好的视角转变点赞
    • @TetsujinnoOni 如果你看到有人写了一个方法public int getAge(Person p){return p.Age;}你会怎么说?我知道如果我看到有人写我会说“你应该使用更有意义的变量而不是缩写”。我看不出为什么同样的逻辑不能同样适用于 lambda。
    • 对于简单的谓词,争论是有意义的变量名会混淆正在发生的事情。在您编写的两种情况下,方法定义的形式都增加了必须区分信号的噪声量,因此增加了命名变量的成本。
    • 对于这么短的方法,我完全可以说 P 足够有意义。形式化是噪音。
    • 有什么不同——当然是范围和大小。毕竟,这就是存在 lambdas 的原因。这就是修改约定的充分理由。
    【解决方案7】:

    在 C# 中,_ 用于类(属性)变量,_ 不用于局部变量。 所以局部变量和类变量最好用有意义的名字。

    例如:

    var personList = (from person in people  where person.Age > 18  select person).ToList();
    

    【讨论】:

      猜你喜欢
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 2023-03-06
      • 1970-01-01
      相关资源
      最近更新 更多