我可以使用lambda语法忽略委托参数吗?

And*_*are 26 c# lambda delegates

我很好奇为什么C#允许我在某些情况下忽略委托参数而不是其他情况.

例如,这是允许的:

Action<int> action = delegate { Console.WriteLine("delegate"); };
Run Code Online (Sandbox Code Playgroud)

但这不是:

Action<int> action = () => Console.WriteLine("lambda");
Run Code Online (Sandbox Code Playgroud)

有没有办法初始化委托并使用lambda忽略参数?我知道我可以在lambda中添加一个参数并修复前一行,但这更像是一个与编译器有关的学术问题,以及为什么或如何工作.

tva*_*son 19

我相信你的第一个样本实际上创建了一个匿名函数,它能够采用身体是单个语句的许多不同签名Console.WriteLine....因为它可以匹配不同的签名,所以它不会导致问题.在第二个示例中,lambda语法本身定义了一个函数,该函数不使用同一主体的参数.显然,后者与定义的Action不一致,因此您会收到错误.

C#匿名方法参考

有一种情况是匿名方法提供lambda表达式中没有的功能.匿名方法使您可以省略参数列表,这意味着可以将匿名方法转换为具有各种签名的委托.lambda表达式无法做到这一点.


cod*_*ast 8

详细说明tvanfosson的答案; C#3.0语言规范(第7.14节)中描述了此行为:

除了以下几点之外,lambda表达式和anonymous-method-expressions的行为是相同的:

•anonymous-method-expressions允许完全省略参数列表,从而产生可转换性以委托任何值参数列表的类型.

•lambda-expressions允许省略和推断参数类型,而anonymous-methods-expressions需要明确声明参数类型.

•lambda表达式的主体可以是表达式或语句块,而anonymous-method-expression的主体必须是语句块.

•由于只有lambda表达式可以具有表达式主体,因此不能将anonymous-method-expression成功转换为表达式树类型(第4.6节).

我认为:

Action<int> action = () => Console.WriteLine("lambda");
Run Code Online (Sandbox Code Playgroud)

相当于:

Action<int> action = delegate() { Console.WriteLine("delegate"); };
Run Code Online (Sandbox Code Playgroud)

这也不会编译.正如Daniel Plaisted所说()明确表示没有任何参数.

如果有一个等同的委托{},它可能是:

Action<int> action = => Console.WriteLine("lambda")
Run Code Online (Sandbox Code Playgroud)

这不是很漂亮,我怀疑它不符合lambda表达的精神.


Mic*_*lGG 5

正如其他人所说,不,你不能跳过将参数声明为lambda.但是,为了清洁,我建议给他们一个名字,如_.例如

foo.Click += (_,__) => { ... }
Run Code Online (Sandbox Code Playgroud)

你并没有忽视它们,但是你表明你不关心它们是什么,也不会使用它们.

  • 任何刚接触过lambdas的人都需要接受培训才能完成任何项目.那是招聘/培训/人力资源问题.我觉得写给那些会被简单的东西弄糊涂的人的好处是没有的. (5认同)
  • 并且会混淆任何新来的lambdas,或者不熟悉你的约定. (2认同)