【问题标题】:What is the recommended way of writing anonymous functions in C#?在 C# 中编写匿名函数的推荐方法是什么?
【发布时间】:2010-11-05 15:06:46
【问题描述】:
var seq = Enumerable.Range(1, 10).Reverse();
var sort1 = seq.OrderBy(i => i);
var sort2 = seq.OrderBy(delegate(int i) { return i; });

我认为 sort2 更明确,但 sort 1 更短。除此之外,我真的不知道有什么区别。这样做的推荐方法是什么?

【问题讨论】:

标签: c# syntax lambda anonymous-methods


【解决方案1】:

Lambda 表达式(IMO)在所有情况下都优于匿名方法除了,在这种情况下你不关心参数,在这种情况下有一个很好的捷径:

// Lambda expression has to specify parameter types
EventHandler x = (sender, args) => Console.WriteLine("Hi");

// Anonymous method can ignore them
EventHandler x = delegate { Console.WriteLine("Hi"); };

Lambda 表达式还有另外两个“问题”IMO:

  • 如果您不使用 C# 3,它们显然不可用。(尽管您可以从 VS2008 定位 .NET 2.0 并仍然使用它们。)
  • 无参数 lambda 表达式的语法有些笨拙:

    () => stuff
    

【讨论】:

  • lambda 必须指定参数类型吗? EventHandler x = () => Console.WriteLine("Hi");
  • 这是明确指定一个空的参数列表 - 这意味着它不能转换为 EventHandler。
  • 在 C#4 中 ()=>stuff 会变成 _ => 的东西吗?
  • 值得一提的是,除了语法简洁之外,Lambda 与委托相比还有一个显着优势,即编译器可以根据需要将它们处理成委托或表达式树。一种可以以编程方式操作作为 lambda 传入的表达式的功能。
  • @JonSkeet 为什么() => stuff 很笨重? delegate { return stuff; } 不是更笨重吗?
【解决方案2】:

在可能的情况下,我更喜欢 lambda 语法 (sort1)。我只在需要的地方使用更详细的语法。我认为额外的东西是非生产性代码,它们会妨碍理解我在写什么。

编辑:当然,除非我正在开发 .NET 2.0 应用程序,否则您不能使用 lambda 语法。然后,我很高兴我至少有匿名方法。

【讨论】:

  • 只要您使用 VS2008 并以 .NET 2.0 为目标,您就可以将 lambdas 用于 .NET 2.0 项目。值得区分语言版本和框架版本。
【解决方案3】:

我发现这取决于场景,因为重要的方面是确保您的代码的意图为未来的维护者提供了良好的文档记录。因此,有时 lambda 效果最好,但有时匿名方法是更好的选择。需要更多参数的 lambdas 的问题是语法开始看起来很混乱,因此有时使用匿名方法委托语法来提供更易于识别的结构会很有用。

在您给出的示例中,lambda 是更好的选择,因为它清晰简洁;但是,在声明内联事件处理程序时,匿名方法可能会提供更好的解决方案(就可维护性而言)。

【讨论】:

  • 当您说“其他时候委托是更好的选择”时,我认为您的意思是“其他时候匿名方法是更好的选择”。在这种情况下,两个表达式都被转换为委托。
  • @Jon:是的 - 我被我的话绊倒了。 :)
  • 别太担心 - 我只是一个庞大的术语书呆子:)(当然,这并不意味着我总是正确!)
  • @Jon:我比你想象的更被称为书呆子 - 英国人被这些美国人包围,语言成为一个问题。
【解决方案4】:

我喜欢委托语法胜过 lambda 表达式的地方很少(我只能想到一个)...

public event Action Evt = delegate {};
public event Action Evt = () => { };

...例如。其余的时间,委托只是妨碍。根据乔恩的评论...

public event EventHandler Evt = delegate {};
public event EventHandler Evt = (s,ea) => { };

【讨论】:

  • 实际上这是事件位的一个坏例子,因为 Action 不带任何参数 - lambda 表达式在这里很好。将其更改为 EventHandler 并且 lambda 表达式变得丑陋,因为您必须为参数命名,即使您不使用它们。
【解决方案5】:

据我所知,这两种方法都会生成完全相同的 IL 代码(至少在本例中如此),所以这确实是个人喜好问题。我经常觉得 lambda 味道更好。

【讨论】:

    【解决方案6】:

    sort1 - 我认为 Lambda 是编写匿名方法的首选方式

    【讨论】:

    • 只是为了成为一个庞大的书呆子(嘿,我正在评论所有其他答案:) 匿名方法根据定义是 sort2 中看到的语法。 lambda 表达式和匿名方法都算作匿名函数;两者都可以转换为委托类型;只有 lambda 表达式可以转换为表达式树。
    【解决方案7】:

    我更喜欢 lambda 表达式,因为它们提供了最简洁的语法,并且类似于函数式编程语言中的 lambda,而这种构造最初来自该语言。当表达式包含多个语句或非功能构造时,我将使用delegate。无参数、多行或显式类型的 lambda 表达式可能看起来有些奇怪,因此失去了它们的主要优势(更具可读性)。

    g = (x => 2 * f(x) + 1); // Nice functional one-liner
    
    // but
    
    action = delegate (int arg) {
        SendSystemMessage(arg);
        Console.WriteLine("Got value: {0}", arg);
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-05
      • 1970-01-01
      • 2012-02-05
      • 2012-02-21
      相关资源
      最近更新 更多