IComparable
hanya bekerja satu arah
Katakanlah Anda memiliki Employee
kelas. Dalam satu tampilan, Anda ingin menampilkan semua yang Employees
diurutkan berdasarkan nama - di tampilan lain, berdasarkan alamat. Bagaimana Anda akan mencapai itu? Tidak dengan IComparable
, setidaknya tidak dengan cara idiomatis.
IComparable
memiliki logika di tempat yang salah
Antarmuka digunakan dengan memanggil .Sort()
. Dalam tampilan yang menunjukkan Customer
diurutkan berdasarkan nama, tidak ada kode sama sekali untuk mengimplikasikan bagaimana kode itu akan diurutkan.
Di sisi lain, Customer
kelas mengasumsikan bagaimana akan digunakan - dalam hal ini, bahwa kelas akan digunakan dalam daftar yang diurutkan berdasarkan nama.
IComparable
digunakan secara implisit
Dibandingkan dengan alternatif, sangat sulit untuk melihat di mana logika perbandingan digunakan - atau jika sama sekali. Dengan asumsi IDE standar Anda dan mulai dari Customer
kelas, saya harus
- Cari semua referensi
Customer
- Temukan referensi yang digunakan dalam daftar
- Periksa apakah daftar itu pernah
.Sort()
memanggil mereka
Yang mungkin lebih buruk, jika Anda menghapus IComparable
implementasi yang masih digunakan, Anda tidak mendapatkan kesalahan atau peringatan. Satu-satunya hal yang akan Anda dapatkan adalah perilaku yang salah di semua tempat yang terlalu tidak jelas untuk Anda pikirkan.
Masalah-masalah ini digabungkan, ditambah perubahan persyaratan
Alasan saya berpikir tentang ini adalah karena itu salah bagi saya. Saya telah dengan senang hati menggunakan IComparable
aplikasi saya selama 2 tahun sekarang. Sekarang, persyaratannya berubah dan masalahnya perlu disortir dalam 2 cara berbeda. Telah memperhatikan bahwa tidak menyenangkan melalui langkah-langkah yang dijelaskan di bagian sebelumnya.
Pertanyaan
Masalah-masalah ini membuat saya berpikir IComparable
lebih rendah daripada IComparer
atau .OrderBy()
, sampai tidak melihat adanya use case yang valid yang tidak akan dilayani dengan lebih baik oleh alternatif.
Apakah selalu lebih baik menggunakan IComparer
atau LINQ, atau adakah keuntungan / kasus penggunaan yang tidak saya lihat di sini?
sumber
IComparable
lagi, yang memperkuat poin saya.SortedXXX
koleksi, mereka memerlukan elemen yang disimpanIComparable
atauIComparer
disediakan. Juga perhatikan, bahwa itu sepele untuk membalik urutan urutan alami dengan satu pembanding dan membuatnya bekerja dengan semuaIComparable
objek.IComparable
dianggap sebagai mekanisme perbandingan standar .IComparer
digunakan ketika Anda ingin mengganti mekanisme perbandingan default.ReverseComparer<T>
: gist.github.com/jackfarrington/078e7af7bc82482aa634Jawaban:
IComparable
memiliki batasan yang Anda sebutkan, itu benar. Ini adalah antarmuka yang sudah tersedia di .NET framework 1.0, di mana alternatif fungsional dan Linq tidak tersedia. Jadi ya, orang mungkin melihatnya sebagai elemen kerangka kerja usang yang terutama disimpan untuk kompatibilitas mundur.Namun, untuk banyak struktur data sederhana, satu cara penyortiran mungkin cukup atau alami. Untuk kasus ini, memiliki satu tempat kanonik untuk menerapkan hubungan pesanan masih merupakan cara yang baik untuk menjaga kode KERING, alih-alih selalu mengulangi logika yang sama dalam setiap panggilan ke
OrderBy
semua tempat.Anda telah "dengan senang hati menggunakan IComparable dalam aplikasi Anda selama 2 tahun sekarang", seperti yang Anda tulis, jadi bagi saya sepertinya ini sangat membantu Anda untuk waktu yang lama. Saat Anda sekarang harus memvalidasi, mengubah, dan menguji semua panggilan
Sort
, itu mungkin juga merupakan tanda Anda melakukan jenis logika penyortiran yang sama di banyak tempat, yang bukan merupakan kesalahanIComparable
. Jadi ini bisa menjadi kesempatan untuk lebih memusatkan logika ini di satu tempat, membuat kode Anda lebih KERING.sumber
IComparable
, semua kode sortir yang sudah ada sebelumnya akan tersentuh dalam pandangan masing-masing, sementara saya hanya akan menambahkan kode sortir baru untuk tampilan baru.IComparable
implementasi yang Anda tulis?IComparable
, Anda mendapatkan implementasi default secara gratis, dan kadang-kadang Anda bahkan tidak perlu menulis implementasi itu.BigInteger
. Jika tidak mengimplementasikan operator perbandingan / antarmuka, bagaimana Anda bahkan dapat mengimplementasikan IComparer sendiri ? Anda memerlukan akses ke struktur data internal untuk melakukannya secara efisien, atau sama sekali. Misalkan Anda memiliki tipe seperti Pelanggan; sifat masyarakat yang ingin mengurutkan do memiliki comparers. Bagi saya itulah bedanya: implementIComparable<T>
jika tidak masuk akal untuk mengharapkan penelepon mengimplementasikan komparator.If I hadn't used IComparable, all the pre-existing sorting code would have been left untouched in their respective views, while I'd only add new sorting code for the new view.
Hanya karenaIComparable
merupakan solusi yang lebih baik pada saat itu , tidak berarti itu adalah solusi terbaik saat ini . Komentar pertama Anda di sini menyiratkan bahwa "tidak bisa dibandingkan atau tidak sama sekali", yang tidak benar, masalahnya bisa diselesaikan dengan berbagai cara. Aplikasi dapat tumbuh dalam ukuran / skala, dan hal-hal yang dulunya cocok mungkin tidak dapat mengikuti permintaan aplikasi yang semakin meningkat.Saya setuju dengan sentimen Anda tentang
IComparable
Lihat saja komentarnya
Array.Sort()
IComparable
antarmuka agar dapat dibandingkan dengan setiap elemen lainnya dalam array. (atau pengecualian dilemparkan)Kami mungkin tidak akan pernah sekarang memotivasi, Namun! pertimbangkan
object.Equals()
metode pada setiap objek yang memungkinkan Anda membandingkan objek satu sama lain untuk melihat apakah mereka "sama"Anda sudah memilikinya di sana, tetapi telah ditugaskan untuk menambahkan
Array.Sort()
yang mungkin ingin Anda tambahkanobject.Compare(object)
sumber