Ini hanya pertanyaan rasa ingin tahu yang bertanya-tanya apakah ada yang punya jawaban bagus untuk:
Di perpustakaan .NET Framework Class kami memiliki misalnya dua metode ini:
public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate
)
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
Mengapa mereka menggunakan Func<TSource, bool>
bukan Predicate<TSource>
? Sepertinya Predicate<TSource>
hanya digunakan oleh List<T>
dan Array<T>
, sementara Func<TSource, bool>
digunakan oleh hampir semua Queryable
dan Enumerable
metode dan metode penyuluhan ... ada apa dengan itu?
Jawaban:
Sementara
Predicate
telah diperkenalkan pada saat yang sama ituList<T>
danArray<T>
, dalam. Net 2.0, perbedaanFunc
danAction
varian berasal dari. Net 3.5.Jadi
Func
predikat tersebut digunakan terutama untuk konsistensi dalam operator LINQ. Pada .net 3.5, tentang penggunaanFunc<T>
danAction<T>
status pedoman :sumber
Saya sudah bertanya-tanya sebelumnya. Saya suka
Predicate<T>
delegasi - bagus dan deskriptif. Namun, Anda perlu mempertimbangkan kelebihanWhere
:Itu memungkinkan Anda untuk memfilter berdasarkan pada indeks entri juga. Itu bagus dan konsisten, sedangkan:
tidak akan.
sumber
Where
metode ekstensi adalahpredicate
. Heh = P.Tentunya alasan sebenarnya untuk menggunakan
Func
alih-alih delegasi tertentu adalah bahwa C # memperlakukan delegasi yang dideklarasikan secara terpisah sebagai tipe yang sama sekali berbeda.Meskipun
Func<int, bool>
danPredicate<int>
keduanya memiliki argumen dan tipe pengembalian yang sama, keduanya tidak kompatibel dengan penugasan. Jadi jika setiap perpustakaan mendeklarasikan tipe delegasinya sendiri untuk setiap pola delegasi, perpustakaan tersebut tidak akan dapat beroperasi kecuali pengguna memasukkan "bridging" delegate untuk melakukan konversi.Dengan mendorong semua orang untuk menggunakan Fungsi, Microsoft berharap ini akan mengurangi masalah tipe delegasi yang tidak kompatibel. Delegasi setiap orang akan bermain bersama dengan baik, karena mereka hanya akan dicocokkan berdasarkan pada parameter / tipe pengembalian mereka.
Itu tidak menyelesaikan semua masalah, karena
Func
(danAction
) tidak dapat memilikiout
atauref
parameter, tetapi mereka kurang umum digunakan.Pembaruan: dalam komentar Svish mengatakan:
Ya, selama program Anda hanya menetapkan metode untuk didelegasikan, seperti pada baris pertama dari
Main
fungsi saya . Kompiler secara diam-diam menghasilkan kode ke objek delegasi baru yang meneruskan ke metode. Jadi dalamMain
fungsi saya , saya bisa berubahx1
menjadi tipeExceptionHandler2
tanpa menyebabkan masalah.Namun, pada baris kedua saya mencoba untuk menetapkan delegasi pertama ke delegasi lain. Bahkan berpikir bahwa tipe delegasi ke-2 memiliki parameter yang persis sama dan tipe yang dikembalikan, kompiler memberikan kesalahan
CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'
.Mungkin ini akan membuatnya lebih jelas:
Metode saya
IsNegative
adalah hal yang sangat baik untuk ditugaskan kep
danf
variabel, selama saya melakukannya secara langsung. Tapi kemudian saya tidak bisa menetapkan salah satu variabel tersebut ke yang lain.sumber
Func<T, bool>
atauPredicate<T>
lebih daripada memiliki jenis yang disimpulkan oleh kompiler.Saran (dalam 3.5 dan di atas) adalah menggunakan
Action<...>
danFunc<...>
- untuk "mengapa?" - satu keuntungan adalah "Predicate<T>
" hanya bermakna jika Anda tahu apa arti "predikat" - jika tidak, Anda perlu melihat objek-browser (dll) untuk menemukan signatute.Sebaliknya
Func<T,bool>
mengikuti pola standar; Saya dapat segera mengatakan bahwa ini adalah fungsi yang mengambilT
dan mengembalikan abool
- tidak perlu memahami terminologi apa pun - cukup terapkan tes kebenaran saya.Untuk "predikat" ini mungkin baik-baik saja, tetapi saya menghargai upaya untuk membuat standar. Ini juga memungkinkan banyak kesamaan dengan metode terkait di daerah itu.
sumber