_ =>ラムダ式でこの下線はどういう意味ですか?


111

ラムダ式とは_=> exprどういう意味ですか?

_ラムダへの入力としての目的は何ですか?

例:

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

8
こんにちは、StackOverflowへようこそ。私はあなたの質問を少し自由に編集して、有用な回答を得る機会を増やしました。
Lasse V. Karlsen、

がであると仮定listするとIEnumerable<T>、彼らは使用した可能性がある(そして使用する必要があった)sum = list.Count();
BlueRaja-Danny Pflughoeft

これは、競合を引き起こす別の場所で使用される可能性がある新しい変数名でスコープを「汚染」するのを防ぐために使用できると思います。
Tim Schmelter、2018年

回答:


83

これは、パラメータを気にしないときに使用される規則です。


3
Haskellや他の関数型言語ではより一般的です。それはそこから来ていると思います。
Gabe Moothart

10
Haskellでは、ML、Scalaなどが_パターンマッチングのワイルドカード文字です。それは基本的には「私は気にしない、これを常に一致させたい」という意味です。この「気にしない」は、気にしないものに名前付けるときに持ち越され、そこから他のプログラミング言語に波及します。たとえば、Rubyでは_特別な意味はまったくありませんが、Ruby ではこの例と同じ意味で使用されます。
イェルクWミッターク

@JörgWMittag2010年5月はTrueですが、2010年6月の時点ではありません。素晴らしいタイミングです!:) stackoverflow.com/q/6397078/38765
Andrew Grimm

38

これはパラメーター名ですが、有用な名前ではありませんが、コードをコンパイルするために式パラメーターあることを指定する必要ある、実際には気にしない場合に(一部の規則によって)通常使用される名前ですそれについて、あなたはそれを無視するつもりです。

これは基本的に、C#の正当な識別子が構成する構文を利用しており、識別子はアンダースコアで始まり、他に何も含まないため、単なるパラメーター名です。

あなたは簡単に書くことができたでしょう:

var _ = 10;

1
_の代わりに、()を使用できますか?
amesh 2015年

2
使ってみましたか?
Lasse V. Karlsen、2015年

はい、ラムダ式を使用してスレッドを作成するときに使用しました。Thread t= new Thread(()=>doSomething(x,y)); t.start();
amesh、2015年

私が想定しているのは、_を使用すると、コレクションの各変数が使用されていない場合でもラムダ式に渡されることです。しかし、()を使用すると、それが起こらない場合があります。つまり、ラムダより少ないパラメータを意味します。
amesh、2015年

ForEachメソッド呼び出しを使用してそれを試す必要があります。Threadコンストラクターには、パラメーターを受け取らないデリゲートを取るオーバーロードがあります。代わりにパラメーターを受け取るデリゲートをとるForEachのようなメソッドを呼び出してみてください。
Lasse V. Karlsen、2015年


10

ラムダ式は主に短い匿名コードで使用されるため、コードブロックで変数を使用しない場合でも変数の名前が不要になる場合があるため、短い規則の場合は_を指定するだけです。


7

また_ => _.method()、1行のメソッド呼び出しラムダを使用することで、命令の認知的重みが軽減されます。特にジェネリックスを使用する場合x => x.method()、「この「x」は何ですか?空間の座標ですか?」という一瞬の考慮を追加するだけです。

次のケースを考えてみましょう:

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

Generics呼び出しで使用すると、この場合のアンダースコアは「バイパス記号」として機能します。これは冗長性を回避し、引数の型が明白であり、使用から推測できることを定義します-型宣言の繰り返しを防ぐために 'var'を使用する場合と同じです。client=>client.Init()ここに書いても、意味が追加されることなく、命令が長くなるだけです。

明らかに、これはメソッドに渡されるパラメーターには適用されません。例えば。:Do( id=>Log(id) );

ラムダ識別子がジェネリック定義から切り離されるため、ワンライナーではなくコードのブロックを使用する場合、メソッド呼び出しの単一アンダースコアパラメータの使用はほとんど正当化できません。一般に、同じ識別子を再利用する場合は、わかりやすい名前を付けてください。

要するに、冗長性は曖昧性解消、特に匿名デリゲートの作成を単純化するために最初に作成されたラムダに対してのみ正当化できるということです。いずれの場合も、読みやすさと簡潔さのバランスを取りながら、常識を使用する必要があります。シンボルが実際の機能への「フック」にすぎない場合は、1文字の識別子で十分です。これは、Forループと、インデクサーとしての "i"および "j"文字の場合に当てはまります。


2
このアプローチの+1!私はラムダでアンダースコアを使用して「認識の重みを減らす」唯一の人でしたが、このパラメーターが使用されていないことを示したわけではありません。アンダースコアを使用すると、特に多くの連鎖があり、LINQクエリの場合によくあるように、型をすぐに推測できる場合、読みやすくなります。
Varvara Kalinina 2017年

3
Do(id => Log(id))はと省略しDo(Log)た方が適切です。
Aluan Haddad
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.