Saya melihat implementasi baru di C # 7.0 dan saya merasa menarik bahwa mereka telah mengimplementasikan fungsi lokal tetapi saya tidak bisa membayangkan skenario di mana fungsi lokal lebih disukai daripada ekspresi lambda, dan apa perbedaan antara keduanya.
Saya mengerti bahwa lambda adalah anonymous
fungsi sedangkan fungsi lokal tidak, tetapi saya tidak bisa menemukan skenario dunia nyata, di mana fungsi lokal memiliki kelebihan dibandingkan dengan ekspresi lambda
Contoh apa pun akan sangat dihargai. Terima kasih.
Jawaban:
Ini dijelaskan oleh Mads Torgersen dalam Catatan Rapat Desain C # di mana fungsi-fungsi lokal pertama kali dibahas :
Untuk mengembangkannya lagi, keuntungannya adalah:
Performa.
Saat membuat lambda, delegasi harus dibuat, yang merupakan alokasi yang tidak perlu dalam kasus ini. Fungsi lokal benar-benar hanya fungsi, tidak ada delegasi yang diperlukan.
Juga, fungsi lokal lebih efisien dengan menangkap variabel lokal: lambdas biasanya menangkap variabel ke dalam kelas, sementara fungsi lokal dapat menggunakan struct (lulus menggunakan
ref
), yang lagi-lagi menghindari alokasi.Ini juga berarti memanggil fungsi lokal lebih murah dan dapat digarisbawahi, mungkin meningkatkan kinerja lebih jauh.
Fungsi lokal dapat bersifat rekursif.
Lambdas juga bisa bersifat rekursif, tetapi membutuhkan kode yang canggung, di mana Anda pertama kali menetapkan
null
variabel delegasi dan kemudian lambda. Fungsi lokal secara alami dapat bersifat rekursif (termasuk saling recursive).Fungsi lokal bisa bersifat generik.
Lambdas tidak bisa generik, karena mereka harus ditugaskan ke variabel dengan tipe konkret (tipe itu dapat menggunakan variabel generik dari lingkup luar, tapi itu bukan hal yang sama).
Fungsi lokal dapat diimplementasikan sebagai iterator.
Lambdas tidak dapat menggunakan kata kunci
yield return
(danyield break
) untuk mengimplementasikanIEnumerable<T>
fungsi -urnurning. Fungsi lokal bisa.Fungsi lokal terlihat lebih baik.
Ini tidak disebutkan dalam kutipan di atas dan mungkin hanya bias pribadi saya, tapi saya pikir sintaks fungsi normal terlihat lebih baik daripada menugaskan lambda ke variabel delegasi. Fungsi lokal juga lebih ringkas.
Membandingkan:
sumber
Func<int, int, int> f = (x, y) => x + y; f(arg1:1, arg2:1);
.object
. Jadi, lambdas bisa menggunakan struct, tetapi harus dikotak, sehingga Anda masih memiliki alokasi tambahan.Selain jawaban hebat svick, ada satu lagi keuntungan fungsi lokal:
Mereka dapat didefinisikan di mana saja dalam fungsi, bahkan setelah
return
pernyataan.sumber
#region Helpers
di bagian bawah fungsi, sehingga untuk menghindari kekacauan di dalam fungsi itu dan terutama menghindari kekacauan di kelas utama.Jika Anda juga bertanya-tanya bagaimana cara menguji fungsi lokal Anda harus memeriksa JustMock karena memiliki fungsi untuk melakukannya. Berikut adalah contoh kelas sederhana yang akan diuji:
Dan inilah bagaimana tes ini terlihat:
Berikut ini tautan ke dokumentasi JustMock .
Penolakan. Saya adalah salah satu pengembang yang bertanggung jawab untuk JustMock .
sumber
.DoNothing().OccursOnce();
Dan kemudian menegaskan bahwa panggilan itu dilakukan dengan memanggilMock.Assert(foo);
metode. Jika Anda tertarik bagaimana skenario lain didukung, Anda bisa membaca artikel bantuan Penegasan Kejadian kami .Saya menggunakan fungsi sebaris untuk menghindari tekanan pengumpulan sampah secara khusus ketika berhadapan dengan metode yang berjalan lebih lama. Katakanlah seseorang ingin mendapatkan 2 tahun atau memasarkan data untuk simbol ticker yang diberikan. Juga, seseorang dapat mengemas banyak fungsionalitas dan logika bisnis jika diperlukan.
apa yang dilakukan adalah membuka koneksi soket ke server dan mengulangi data yang mengikat suatu peristiwa ke suatu peristiwa. Seseorang dapat memikirkannya dengan cara yang sama seperti kelas dirancang, hanya satu yang tidak menulis metode pembantu di semua tempat yang benar-benar hanya berfungsi untuk satu fungsi saja. di bawah ini adalah beberapa contoh bagaimana ini terlihat, harap dicatat bahwa saya menggunakan variabel dan metode "pembantu" di bawah yang terakhir. Pada akhirnya saya dengan baik menghapus event handler, jika kelas Exchange saya akan eksternal / disuntikkan saya tidak akan memiliki pendaftar event pending yang terdaftar
Anda dapat melihat keuntungan seperti yang disebutkan di bawah ini, di sini Anda dapat melihat contoh implementasi. Harapan itu membantu menjelaskan manfaatnya.
sumber