Mengapa Anda tidak bisa menggunakan parameter ref atau out dalam ekspresi lambda?
Saya menemukan kesalahan hari ini dan menemukan solusi tetapi saya masih penasaran mengapa ini adalah kesalahan waktu kompilasi.
CS1628 : Tidak dapat menggunakan dalam parameter ref atau out 'parameter' di dalam metode anonim, ekspresi lambda, atau ekspresi permintaan
Berikut ini contoh sederhana:
private void Foo()
{
int value;
Bar(out value);
}
private void Bar(out int value)
{
value = 3;
int[] array = { 1, 2, 3, 4, 5 };
int newValue = array.Where(a => a == value).First();
}
Jawaban:
Lambdas memiliki penampilan mengubah masa hidup variabel yang mereka tangkap. Misalnya ekspresi lambda berikut ini menyebabkan parameter p1 hidup lebih lama dari bingkai metode saat ini karena nilainya dapat diakses setelah bingkai metode tidak lagi di tumpukan
Properti lain dari variabel yang ditangkap adalah bahwa perubahan pada variabel juga terlihat di luar ekspresi lambda. Misalnya cetakan berikut 42
Kedua properti ini menghasilkan serangkaian efek tertentu yang terbang di hadapan parameter ref dengan cara berikut
Ini adalah properti yang agak tidak kompatibel dan merupakan salah satu alasan mereka tidak diizinkan dalam ekspresi lambda.
sumber
ref
ekspresi lambda di dalam, tetapi keinginan untuk menggunakannya belum terpenuhi.Di bawah tenda, metode anonim diimplementasikan dengan mengangkat variabel yang ditangkap (yang merupakan inti dari badan pertanyaan Anda) dan menyimpannya sebagai bidang dari kelas yang dihasilkan kompiler. Tidak ada cara untuk menyimpan parameter
ref
atauout
sebagai bidang. Eric Lippert membahasnya dalam entri blog . Perhatikan bahwa ada perbedaan antara variabel yang ditangkap dan parameter lambda. Anda dapat memiliki "parameter formal" seperti berikut ini karena mereka bukan variabel yang ditangkap:sumber
Anda dapat tetapi Anda harus secara eksplisit mendefinisikan semua tipe demikian
Namun, tidak valid
Adalah benar
sumber
ref
atauout
, di dalam lambda. Jelas jika Anda membaca kode contoh (coba lagi untuk membacanya lagi). Jawaban yang diterima dengan jelas menjelaskan alasannya. Jawaban Anda adalah tentang menggunakanref
atauout
parameter ke lambda. Sama sekali tidak menjawab pertanyaan dan berbicara tentang sesuatu yang lainKarena ini adalah salah satu hasil teratas untuk "C # lambda ref" di Google; Saya merasa perlu mengembangkan jawaban di atas. Sintaks delegasi anonim yang lebih tua (C # 2.0) berfungsi dan mendukung tanda tangan yang lebih kompleks (juga penutupan). Delegasi Lambda dan anonim paling tidak telah berbagi implementasi yang dirasakan dalam backend compiler (jika mereka tidak identik) - dan yang paling penting, mereka mendukung penutupan.
Apa yang saya coba lakukan ketika saya melakukan pencarian, untuk menunjukkan sintaks:
Perlu diingat bahwa Lambdas lebih aman secara prosedural dan matematis (karena promosi nilai referensi yang disebutkan sebelumnya): Anda mungkin membuka sekaleng cacing. Pikirkan baik-baik ketika menggunakan sintaks ini.
sumber
(a, b, c, ref d) => {...}
danref
digarisbawahi dengan pesan kesalahan "Parameter '4' harus dinyatakan dengan kata kunci 'ref'". Telapak tangan! PS apa itu "promosi nilai referensi"?Dan mungkin ini?
sumber