Saya datang untuk menggunakan LINQ dalam pemrograman saya setiap hari. Bahkan, saya jarang, jika pernah, menggunakan loop eksplisit. Saya telah, bagaimanapun, menemukan bahwa saya tidak menggunakan sintaks seperti SQL lagi. Saya hanya menggunakan fungsi ekstensi. Jadi daripada mengatakan:
from x in y select datatransform where filter
Saya menggunakan:
x.Where(c => filter).Select(c => datatransform)
Gaya LINQ apa yang Anda sukai dan apa yang membuat orang lain nyaman dengan tim Anda?
c#
coding-style
linq
Erin
sumber
sumber
Jawaban:
Saya merasa tidak beruntung bahwa sikap Microsoft per dokumentasi MSDN adalah bahwa sintaks kueri lebih disukai, karena saya tidak pernah menggunakannya, tetapi saya menggunakan sintaksis metode LINQ sepanjang waktu. Saya senang bisa memunculkan pertanyaan satu-liner ke isi hati saya. Membandingkan:
Untuk:
Lebih cepat, lebih sedikit garis, dan mata saya terlihat lebih bersih. Sintaks kueri juga tidak mendukung semua operator LINQ standar. Contoh kueri yang baru-baru ini saya lakukan terlihat seperti ini:
Sepengetahuan saya, untuk mereplikasi kueri ini menggunakan sintaks kueri (sejauh mungkin) akan terlihat seperti ini:
Tidak terlihat lebih mudah dibaca oleh saya, dan Anda harus tahu bagaimana cara menggunakan sintaks metode. Secara pribadi saya benar-benar terpikat pada gaya deklaratif yang dimungkinkan oleh LINQ dan menggunakannya dalam situasi apa pun yang memungkinkan - mungkin kadang-kadang merugikan saya. Contoh kasus, dengan sintaks metode saya dapat melakukan sesuatu seperti ini:
Saya membayangkan kode di atas akan sulit dipahami bagi seseorang yang datang ke proyek tanpa dokumentasi yang baik, dan jika mereka tidak memiliki latar belakang yang kuat di LINQ, mereka mungkin tidak memahaminya. Namun, sintaksis metode memperlihatkan beberapa kemampuan yang cukup kuat, untuk dengan cepat (dalam hal baris kode) memproyeksikan kueri untuk mendapatkan informasi agregat tentang beberapa koleksi yang jika tidak akan memerlukan banyak perulangan perulangan yang membosankan. Dalam kasus seperti ini, sintaksis metode sangat kompak untuk apa yang Anda dapatkan darinya. Mencoba melakukan ini dengan sintaks kueri mungkin menjadi agak sulit dengan cepat.
sumber
Saya menemukan sintaks fungsional lebih menyenangkan pada mata. Satu-satunya pengecualian adalah jika saya harus bergabung lebih dari dua set. Gabung () menjadi gila dengan sangat cepat.
sumber
Apakah sudah terlambat untuk menambahkan jawaban lain?
Saya telah menulis satu ton kode LINQ-to-objek dan saya berpendapat bahwa setidaknya dalam domain itu ada baiknya untuk memahami kedua sintaks untuk menggunakan mana saja yang membuat kode lebih sederhana - yang tidak selalu dot-sintaks.
Tentu saja ada saat-saat ketika sintaksis ADALAH cara untuk pergi - yang lain telah menyediakan beberapa kasus ini; namun, saya pikir pemahamannya telah diubah - diberikan rap yang buruk, jika Anda mau. Jadi saya akan memberikan sampel di mana saya percaya pemahaman berguna.
Inilah solusi untuk puzzle substitusi digit: (solusi ditulis menggunakan LINQPad, tetapi dapat berdiri sendiri di aplikasi konsol)
... yang keluaran:
Tidak terlalu buruk, logika mengalir secara linier dan kita dapat melihat bahwa ia muncul dengan solusi tunggal yang benar. Teka-teki ini cukup mudah untuk diselesaikan dengan tangan: dengan alasan bahwa 3>>
N
0, danO
> 4 * N menyiratkan 8> =O
> = 4. Itu berarti ada maksimal 10 kasus untuk diuji dengan tangan (2 untuk-oleh-N
5 untukO
). Saya sudah cukup tersesat - puzzle ini ditawarkan untuk tujuan ilustrasi LINQ.Transformasi Kompiler
Ada banyak yang dilakukan kompiler untuk menerjemahkannya ke dalam sintaks dot-ekuivalen. Selain klausa kedua dan selanjutnya yang
from
SelectMany
biasa diubah menjadi panggilan, kami memilikilet
klausa yang menjadiSelect
panggilan dengan proyeksi, keduanya menggunakan pengidentifikasi transparan . Seperti yang akan saya tunjukkan, harus menyebutkan nama pengidentifikasi ini dalam dot-sintaks menghilangkan dari keterbacaan pendekatan itu.Saya punya trik untuk mengekspos apa yang dilakukan kompiler dalam menerjemahkan kode ini ke sintaks dot. Jika Anda menghapus komentar dari dua baris yang dikomentari di atas dan menjalankannya lagi, Anda akan mendapatkan output berikut:
Menempatkan setiap operator LINQ pada baris baru, menerjemahkan pengidentifikasi "tak terkatakan" ke yang kita bisa "berbicara", mengubah tipe anonim ke bentuk yang mereka kenal dan mengubah
AndAlso
istilah pohon ekspresi untuk&&
memaparkan transformasi yang dilakukan kompiler untuk sampai pada kesetaraan dalam sintaksis titik:Yang jika Anda jalankan Anda dapat memverifikasi bahwa itu lagi menghasilkan:
... tetapi apakah Anda pernah menulis kode seperti ini?
Saya bertaruh jawabannya adalah NONBHN (Tidak Hanya Tidak, Tapi Tidak!) - karena terlalu rumit. Tentu Anda dapat membuat beberapa nama pengidentifikasi yang lebih bermakna daripada "temp0" .. "temp3", tetapi intinya adalah mereka tidak menambahkan apa pun pada kode - mereka tidak membuat kode bekerja lebih baik, mereka tidak membuat kode lebih baik dibaca, mereka hanya jelek kode, dan jika Anda melakukannya dengan tangan, tidak diragukan lagi Anda akan mengacaukannya satu atau tiga waktu sebelum memperbaikinya. Juga, bermain "permainan nama" cukup sulit untuk pengidentifikasi yang bermakna, jadi saya menyambut baik istirahat dari permainan nama yang diberikan kompiler kepada saya dalam pemahaman kueri.
Sampel puzzle ini mungkin tidak cukup nyata bagi Anda untuk dianggap serius; Namun, skenario lain memang ada di mana pemahaman kueri bersinar:
Join
danGroupJoin
: pelingkupan variabel rentang dalamjoin
klausa pemahaman kueri mengubah kesalahan yang mungkin dikompilasi dalam sintaksis titik menjadi kesalahan waktu kompilasi dalam sintaksis pemahaman.from
klausa,join
&join..into
klausa danlet
klausa.Saya tahu lebih dari satu toko teknik di kota asal saya yang telah melarang sintaksis pemahaman. Saya pikir ini sangat disayangkan karena sintaks pemahaman hanyalah alat dan yang berguna pada saat itu. Saya pikir itu seperti mengatakan, "Ada hal-hal yang dapat Anda lakukan dengan obeng yang tidak dapat Anda lakukan dengan pahat. Karena Anda dapat menggunakan obeng sebagai pahat, pahat dilarang untuk selanjutnya di bawah keputusan raja."
sumber
Saran saya adalah menggunakan sintaks pemahaman kueri ketika seluruh ekspresi dapat dilakukan dalam sintaksis pemahaman. Yaitu, saya lebih suka:
untuk
Tapi saya lebih suka
untuk
Saya berharap kami telah membuat beberapa sintaks yang membuatnya lebih baik untuk menggabungkan keduanya. Sesuatu seperti:
Tapi sayangnya kami tidak melakukannya.
Tapi pada dasarnya, ini masalah preferensi. Lakukan yang terlihat lebih baik untuk Anda dan rekan kerja Anda.
sumber
var londonCustomers = from c in ...; int count = londonCustomers.Count();
Seperti SQL adalah cara yang baik untuk memulai. Tetapi karena terbatas (hanya mendukung konstruksi yang didukung bahasa Anda saat ini), akhirnya pengembang beralih ke gaya metode ekstensi.
Saya ingin mencatat bahwa ada beberapa kasus yang dapat dengan mudah diimplementasikan dengan gaya seperti SQL.
Anda juga dapat menggabungkan kedua cara dalam satu permintaan.
sumber
Saya cenderung menggunakan sintaksis non-kueri kecuali saya perlu mendefinisikan variabel di tengah jalan seperti kueri
tapi saya menulis sintaks non-query seperti
sumber
Saya selalu menggunakan fungsi ekstensi karena pemesanan. Ambil contoh sederhana Anda - dalam SQL, Anda menulis pilih pertama - meskipun sebenarnya, di mana dulu dieksekusi. Ketika Anda menulis menggunakan metode ekstensi, maka saya merasa jauh lebih terkendali. Saya mendapatkan Intellisense tentang apa yang ditawarkan, saya menulis beberapa hal sesuai urutannya.
sumber
Saya suka fungsi ekstensi juga.
Mungkin karena itu kurang lompatan sintaks dalam pikiran saya.
Rasanya lebih mudah dibaca oleh mata, terutama jika Anda menggunakan kerangka kerja pihak ketiga yang memiliki linq api.
sumber
Inilah heuristik yang saya ikuti:
Saya pikir lambda dengan gabungan terlihat berantakan dan sulit dibaca.
sumber