_ =>下划线在Lambda表达式中意味着什么?


111

lambda表达式_=> expr是什么意思?

_输入lambda 的目的是什么?

例:

int count = 0;
list.ForEach(_ => count += 1);

8
嗨,欢迎来到StackOverflow。我随意编辑您的问题,以增加获得有用答案的机会,希望您不要介意。
Lasse V. Karlsen

请注意,假设list是an IEnumerable<T>,他们可以(并且应该)刚刚使用过sum = list.Count();
BlueRaja-Danny Pflughoeft

我猜这可以用来防止您用新的变量名“污染”范围,而该变量名可能会在其他地方使用,从而导致冲突。
蒂姆·施密特

Answers:


83

这是当您不关心参数时使用的约定。


3
在Haskell和其他功能语言中更常见。我认为那是它的来历。
·穆阿特

10
在Haskell中,ML,Scala等_是模式匹配中的通配符。它的基本含义是“我不在乎,我一直希望它与之匹配”。然后,在命名您不关心的事物时,这种“我不在乎”就会被保留下来,并扩散到其他编程语言中。例如,即使_在Ruby中绝对没有特殊意义,它在Ruby中也用于表示与本示例相同的含义。
约尔格W¯¯米塔格

@JörgWMittag2010年5月为True,但截至2010年6月尚未生效。绝佳时机!:) stackoverflow.com/q/6397078/38765
安德鲁·格林

38

它是一个参数名称,尽管它不是一个有用的名称,但是当需要指定表达式具有参数以便编译代码时,它通常(根据某些约定)使用该名称,但是您并不在乎关于它,所以您将忽略它。

它基本上是在利用C#中的合法标识符构成的语法,并且由于标识符可以以下划线开头,并且不包含其他任何内容,因此它只是一个参数名称。

您可以轻松地编写以下内容:

var _ = 10;

1
除了_之外,我们可以使用()吗?
amesh

2
您尝试过使用吗?
Lasse V. Karlsen 2015年

是的,我在使用lambda表达式创建线程时使用了它。Thread t= new Thread(()=>doSomething(x,y)); t.start();
amesh

我假设的是,使用_会将集合的每个变量传递给lambda表达式,即使未使用它。但是当我们使用()时可能不会发生。我的意思是参数少了lambda。
amesh

您需要使用ForEach方法调用进行尝试。线程构造函数上有一个重载,该重载接受不带任何参数的委托。尝试调用诸如ForEach之类的方法,该方法采用一个带有参数的委托。
Lasse V. Karlsen 2015年


10

因为lamda表达式主要用在简短的匿名代码中,所以有时不需要变量的名称,即使它们不在代码块中使用变量,因此也只是给_表示简短约定


7

我还第二次使用了_ => _.method()单行方法调用lambda,因为它减少了指令的认知分量。特别是在使用泛型时,编写时x => x.method()只是添加了“这是什么'x'?它是空间坐标吗?”的瞬间考虑。

考虑以下情况:

Initialize<Client> ( _=>_.Init() );

与泛型调用一起使用时,下划线在这种情况下用作“旁路符号”。它避免了冗余,定义了参数的类型是显而易见的,并且可以从用法中推断出-就像您使用'var'来防止重复类型声明时一样。client=>client.Init()在这里写只会增加指令的长度而不会增加任何意义。

显然,这不适用于要传递给方法的参数,该参数应以描述性方式命名。例如。:Do( id=>Log(id) );

当使用代码块而不是单行代码时,方法调用的单下划线参数用法几乎是不合理的,因为lambda标识符已从其泛型定义中断开。通常,当要重复使用相同的标识符时,请为其提供描述性名称。

最重要的是,冗长仅是为了消除歧义,特别是对于lambda是合理的,lambda最初是为了简化匿名代表的创建而创建的。无论如何,都应使用常识,以兼顾易读性和简洁性。如果该符号只是真正功能的“钩子”,那么一个字符标识符就可以了。对于For循环以及使用“ i”和“ j”字母作为索引器的情况就是这样。


2
为此方法+1!尽管我是使用lambdas中的下划线“减少认知权重”的唯一人,但我并不是为了表明未使用此参数。使用下划线确实更容易阅读,尤其是在有很多链接并且您可以立即推断出类型的情况下,尤其是在LINQ查询中!
Varvara Kalinina

3
Do(id => Log(id))最好缩写为Do(Log)
阿兰·哈达德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.