Halo dan selamat datang di StackOverflow. Saya mengambil kebebasan mengedit pertanyaan Anda sedikit untuk meningkatkan kesempatan Anda mendapatkan jawaban yang berguna, harap Anda tidak keberatan.
Lasse V. Karlsen
Perhatikan bahwa, dengan asumsi listadalah IEnumerable<T>, mereka bisa (dan seharusnya) baru saja menggunakansum = list.Count();
BlueRaja - Danny Pflughoeft
Saya rasa ini dapat digunakan untuk mencegah Anda "mencemari" cakupan dengan nama variabel baru yang mungkin digunakan di tempat lain yang akan menyebabkan konflik.
Tim Schmelter
Jawaban:
84
Itu adalah konvensi yang digunakan saat Anda tidak peduli dengan parameternya.
Ini lebih umum di Haskell dan bahasa fungsional lainnya. Saya pikir dari sanalah asalnya.
Gabe Moothart
10
Di Haskell, ML, Scala dan lainnya, _adalah karakter wildcard dalam pencocokan pola. Ini pada dasarnya berarti "Saya tidak peduli, saya selalu ingin ini cocok". "Saya tidak peduli" ini kemudian terbawa ketika sampai pada penamaan hal-hal yang tidak Anda pedulikan dan dari sana, itu menyebar ke bahasa pemrograman lain. Ini, misalnya, juga digunakan di Ruby dengan arti yang sama seperti dalam contoh ini, meskipun _sama sekali tidak memiliki arti khusus di Ruby.
Ini adalah nama parameter, meskipun bukan yang berguna, tetapi itu yang biasanya digunakan (oleh beberapa konvensi) ketika Anda perlu menentukan bahwa ekspresi memiliki parameter untuk mendapatkan kode untuk dikompilasi, tetapi Anda tidak terlalu peduli tentang itu, jadi Anda hanya akan mengabaikannya.
Ini pada dasarnya mengeksploitasi sintaks untuk apa yang merupakan pengenal hukum di C #, dan karena pengenal dapat dimulai dengan garis bawah, dan tidak berisi yang lain, itu hanya nama parameter.
Ya, saya telah menggunakannya saat membuat utas menggunakan ekspresi lambda. Thread t= new Thread(()=>doSomething(x,y)); t.start();
amesh
Apa yang saya asumsikan adalah, penggunaan _ adalah meneruskan setiap variabel collection ke ekspresi lambda meskipun tidak digunakan. Tetapi ketika kita menggunakan () itu mungkin tidak terjadi. Maksud saya parameter kurang lambda.
amesh
Anda perlu mencobanya menggunakan panggilan metode ForEach. Ada kelebihan beban pada konstruktor Thread yang membutuhkan delegasi yang tidak mengambil parameter apa pun. Coba panggil metode, seperti ForEach itu, yang membutuhkan delegasi yang mengambil parameter.
Lasse V. Karlsen
29
_adalah nama variabel yang valid. Mereka hanya digunakan _sebagai variabel.
Karena ekspresi lamda banyak digunakan dalam bentuk kode yang pendek dan anonim sehingga nama variabel terkadang tidak diperlukan, bahkan tidak menggunakan variabel yang ada di blok kode, sehingga hanya memberikan _ singkatnya, konvensi
Saya juga mendukung penggunaan _ => _.method()for one-line, method-call lambda, karena ini mengurangi bobot kognitif instruksi. Khususnya saat menggunakan obat generik, menulis x => x.method()hanya menambahkan pertimbangan sepersekian detik dari "Apa ini 'x'? Apakah itu koordinat dalam ruang?".
Pertimbangkan kasus berikut:
Initialize<Client> ( _=>_.Init() );
Digunakan dengan panggilan Generik, garis bawah dalam kasus ini berfungsi sebagai "simbol bypass". Ini menghindari redundansi, dengan mendefinisikan bahwa tipe argumen sudah jelas dan dapat disimpulkan dari penggunaan - sama seperti ketika Anda menggunakan 'var' untuk mencegah pengulangan deklarasi tipe. Menulis di client=>client.Init()sini hanya akan membuat instruksi lebih lama tanpa menambahkan makna apa pun padanya.
Jelas, ini tidak berlaku untuk parameter yang akan diteruskan ke metode, yang harus dinamai secara deskriptif. Misalnya.:Do( id=>Log(id) );
Penggunaan parameter garis bawah tunggal untuk panggilan metode hampir tidak dapat dibenarkan saat menggunakan blok kode sebagai ganti satu baris, karena pengenal lambda terputus dari definisi generiknya. Secara umum, jika pengenal yang sama akan digunakan kembali, berikan nama deskriptif.
Intinya adalah verbositas hanya dapat dibenarkan untuk disambiguasi, terutama untuk lambda, yang dibuat untuk menyederhanakan pembuatan delegasi anonim di tempat pertama. Bagaimanapun, akal sehat harus digunakan, menyeimbangkan keterbacaan dan keringkasan. Jika simbol hanya "pengait" ke fungsi sebenarnya, satu pengenal karakter sudah cukup. Itulah yang terjadi pada For-loops dan huruf "i" dan "j" sebagai pengindeks.
1 untuk pendekatan ini! Saya pikir saya adalah satu-satunya yang menggunakan garis bawah di lambda untuk "mengurangi bobot kognitif" dan bukan untuk menunjukkan bahwa parameter ini tidak digunakan. Itu membaca lebih mudah dengan garis bawah, terutama jika ada banyak rantai dan Anda dapat segera menyimpulkan jenisnya, seperti yang sering terjadi pada kueri LINQ!
Varvara Kalinina
3
Do(id => Log(id))lebih baik disingkat sebagai Do(Log).
list
adalahIEnumerable<T>
, mereka bisa (dan seharusnya) baru saja menggunakansum = list.Count();
Jawaban:
Itu adalah konvensi yang digunakan saat Anda tidak peduli dengan parameternya.
sumber
_
adalah karakter wildcard dalam pencocokan pola. Ini pada dasarnya berarti "Saya tidak peduli, saya selalu ingin ini cocok". "Saya tidak peduli" ini kemudian terbawa ketika sampai pada penamaan hal-hal yang tidak Anda pedulikan dan dari sana, itu menyebar ke bahasa pemrograman lain. Ini, misalnya, juga digunakan di Ruby dengan arti yang sama seperti dalam contoh ini, meskipun_
sama sekali tidak memiliki arti khusus di Ruby.Ini adalah nama parameter, meskipun bukan yang berguna, tetapi itu yang biasanya digunakan (oleh beberapa konvensi) ketika Anda perlu menentukan bahwa ekspresi memiliki parameter untuk mendapatkan kode untuk dikompilasi, tetapi Anda tidak terlalu peduli tentang itu, jadi Anda hanya akan mengabaikannya.
Ini pada dasarnya mengeksploitasi sintaks untuk apa yang merupakan pengenal hukum di C #, dan karena pengenal dapat dimulai dengan garis bawah, dan tidak berisi yang lain, itu hanya nama parameter.
Anda bisa saja dengan mudah menulis:
sumber
Thread t= new Thread(()=>doSomething(x,y)); t.start();
_
adalah nama variabel yang valid. Mereka hanya digunakan_
sebagai variabel.sumber
Karena ekspresi lamda banyak digunakan dalam bentuk kode yang pendek dan anonim sehingga nama variabel terkadang tidak diperlukan, bahkan tidak menggunakan variabel yang ada di blok kode, sehingga hanya memberikan _ singkatnya, konvensi
sumber
Saya juga mendukung penggunaan
_ => _.method()
for one-line, method-call lambda, karena ini mengurangi bobot kognitif instruksi. Khususnya saat menggunakan obat generik, menulisx => x.method()
hanya menambahkan pertimbangan sepersekian detik dari "Apa ini 'x'? Apakah itu koordinat dalam ruang?".Pertimbangkan kasus berikut:
Initialize<Client> ( _=>_.Init() );
Digunakan dengan panggilan Generik, garis bawah dalam kasus ini berfungsi sebagai "simbol bypass". Ini menghindari redundansi, dengan mendefinisikan bahwa tipe argumen sudah jelas dan dapat disimpulkan dari penggunaan - sama seperti ketika Anda menggunakan 'var' untuk mencegah pengulangan deklarasi tipe. Menulis di
client=>client.Init()
sini hanya akan membuat instruksi lebih lama tanpa menambahkan makna apa pun padanya.Jelas, ini tidak berlaku untuk parameter yang akan diteruskan ke metode, yang harus dinamai secara deskriptif. Misalnya.:
Do( id=>Log(id) );
Penggunaan parameter garis bawah tunggal untuk panggilan metode hampir tidak dapat dibenarkan saat menggunakan blok kode sebagai ganti satu baris, karena pengenal lambda terputus dari definisi generiknya. Secara umum, jika pengenal yang sama akan digunakan kembali, berikan nama deskriptif.
Intinya adalah verbositas hanya dapat dibenarkan untuk disambiguasi, terutama untuk lambda, yang dibuat untuk menyederhanakan pembuatan delegasi anonim di tempat pertama. Bagaimanapun, akal sehat harus digunakan, menyeimbangkan keterbacaan dan keringkasan. Jika simbol hanya "pengait" ke fungsi sebenarnya, satu pengenal karakter sudah cukup. Itulah yang terjadi pada For-loops dan huruf "i" dan "j" sebagai pengindeks.
sumber
Do(id => Log(id))
lebih baik disingkat sebagaiDo(Log)
.