_ => Lambda ifadelerinde bu alt çizgi ne anlama geliyor?


111

Lambda ifadesi ne anlama _=> exprgeliyor?

_Lambda'ya girdi olarak kullanım amacı nedir ?

Misal:

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

8
Merhaba ve StackOverflow'a hoş geldiniz. Yararlı yanıtlar alma şansınızı artırmak için sorunuzu biraz düzenleme özgürlüğünü aldım, umarım aldırmazsınız.
Lasse V. Karlsen

Unutmayın varsayarak listbir olduğunu IEnumerable<T>, onlar olabilir (ve) hemen kullandıksum = list.Count();
BlueRaja - Dany Pflughoeft

Sanırım bu, kapsamı başka bir yerde kullanılabilecek ve bir çatışmaya neden olabilecek yeni bir değişken adıyla "kirletmenizi" önlemek için kullanılabilir.
Tim Schmelter

Yanıtlar:


84

Bu, parametreyi umursamadığınızda kullanılan bir kuraldır.


3
Haskell ve diğer işlevsel dillerde daha yaygındır. Sanırım nereden geliyor.
Gabe Moothart

10
Haskell, ML, Scala ve diğerlerinde, _desen eşleştirmedeki joker karakterdir. Temelde "Umurumda değil, her zaman bunun eşleşmesini istiyorum " anlamına gelir . Bu "umurumda değil", umursamadığınız şeyleri adlandırmaya gelince taşınır ve oradan diğer programlama dillerine yayılır. Örneğin, Ruby'de _kesinlikle özel bir anlamı olmamasına rağmen , Ruby'de de bu örnekteki ile aynı anlama gelmek için kullanılır .
Jörg W Mittag

@ JörgWMittag Mayıs 2010'da doğru, ancak Haziran 2010 itibarıyla değil. Harika zamanlama! :) stackoverflow.com/q/6397078/38765
Andrew Grimm

38

Kullanışlı olmasa da bir parametre adıdır, ancak ifadenin sahip olduğunu belirtmeniz gerektiğinde (bazı kurallar tarafından) tipik olarak kullanılan addır. derleme kodu almak için bir parametre, ancak bakım gerçekten yok hakkında, bu yüzden onu görmezden geleceksin.

Temelde C # 'daki yasal bir tanımlayıcının oluşturduğu sözdiziminden yararlanıyor ve bir tanımlayıcı bir alt çizgiyle başlayıp başka hiçbir şey içermediğinden, sadece bir parametre adıdır.

Kolayca yazabilirdin:

var _ = 10;

1
_ Yerine () kullanabilir miyiz?
amesh

2
Bunu kullanmayı denedin mi?
Lasse V. Karlsen

Evet, lambda ifadesini kullanarak bir iş parçacığı oluştururken kullandım. Thread t= new Thread(()=>doSomething(x,y)); t.start();
amesh

Varsaydığım şey, _ kullanımı, koleksiyonun her değişkenini kullanılmasa bile lambda ifadesine geçiriyor. Ancak () kullandığımızda bu gerçekleşmeyebilir. Parametre daha az lambda demek istiyorum.
amesh

ForEach yöntem çağrısını kullanarak denemeniz gerekir. Thread yapıcısında herhangi bir parametre almayan bir temsilci alan bir aşırı yük vardır. Bunun yerine parametre alan bir temsilci alan ForEach gibi bir yöntemi çağırmayı deneyin.
Lasse V.Karlsen


10

Lamda ifadesi çoğunlukla kısa, anonim bir kodda kullanıldığından, değişkenin adı bazen gerekli değildir, değişkeni kod bloğunda kullanmasalar bile, kısa bir kural için sadece _ verirler.


7

Ayrıca _ => _.method(), tek satırlık, yöntem çağrısı lambdas'ın kullanımını da ikinci kez yapıyorum , çünkü bu, talimatın bilişsel ağırlığını azaltır. Özellikle jenerikleri kullanırken yazı x => x.method(), "Bu 'x' nedir? Uzayda bir koordinat mı?"

Şu durumu düşünün:

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

Bir Generics çağrısıyla kullanıldığında, bu durumda alt çizgi bir "baypas simgesi" olarak çalışır. Bir tür bildiriminin tekrarlanmasını önlemek için 'var' kullandığınızda olduğu gibi, argüman türünün açık olduğunu ve kullanımdan çıkarılabileceğini tanımlayarak fazlalıktan kaçınır. client=>client.Init()Burada yazmak , talimatı herhangi bir anlam katmadan daha uzun hale getirir.

Açıkçası, bu, açıklayıcı olarak adlandırılması gereken yönteme iletilecek parametreler için geçerli değildir. Örneğin.:Do( id=>Log(id) );

Yöntem çağrıları için tek alt çizgi parametresi kullanımı, lambda tanımlayıcısının jenerik tanımından bağlantısı kesildiği için, tek satırlık yerine bir kod bloğu kullanıldığında pek de haklı gösterilemez. Genel olarak, aynı tanımlayıcı yeniden kullanılacaksa ona açıklayıcı bir ad verin.

Sonuç olarak, ayrıntı, özellikle anonim delegelerin ilk etapta oluşturulmasını basitleştirmek için yaratılan lambdalar için, yalnızca belirsizliği ortadan kaldırmak için haklı çıkarılabilir. Her durumda, okunaklılığı ve özlü olmayı dengeleyerek sağduyu kullanılmalıdır. Sembol, gerçek işlevselliğe yalnızca bir "kanca" ise, bir karakter tanımlayıcı mükemmel şekilde iyidir. For-döngüleri ve indeksleyici olarak "i" ve "j" harflerinde durum böyledir.


2
Bu yaklaşım için +1! Lambdalarda "bilişsel ağırlığı azaltmak" için altçizgi kullanan tek kişi bendim ve bu parametrenin kullanılmadığını göstermek için değil. Alt çizgilerle daha kolay okunur, özellikle çok fazla zincirleme varsa ve LINQ sorgularında sıklıkla olduğu gibi türü hemen anlayabilirsiniz!
Varvara Kalinina

3
Do(id => Log(id))olarak kısaltılması daha iyidir Do(Log).
Aluan Haddad
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.