Saya ingin Food
kelas saya dapat menguji setiap kali itu sama dengan contoh lain dari Food
. Saya nantinya akan menggunakannya melawan Daftar, dan saya ingin menggunakan List.Contains()
metodenya. Haruskah saya menerapkan IEquatable<Food>
atau hanya menimpanya Object.Equals()
? Dari MSDN:
Metode ini menentukan kesetaraan dengan menggunakan pembanding kesetaraan default, seperti yang didefinisikan oleh implementasi objek dari metode IEquatable.Equals untuk T (jenis nilai dalam daftar).
Jadi pertanyaan saya berikutnya adalah: fungsi / kelas mana dari kerangka NET yang digunakan Object.Equals()
? Haruskah saya menggunakannya di tempat pertama?
Jawaban:
Alasan utamanya adalah kinerja. Ketika obat generik diperkenalkan di NET 2.0 mereka dapat menambahkan sekelompok kelas rapi seperti
List<T>
,Dictionary<K,V>
,HashSet<T>
, dll Struktur ini menggunakan beratGetHashCode
danEquals
. Tetapi untuk tipe nilai ini diperlukan tinju.IEquatable<T>
memungkinkan struktur menerapkan metode yang sangat diketikEquals
sehingga tidak ada tinju yang diperlukan. Dengan demikian kinerjanya jauh lebih baik ketika menggunakan tipe nilai dengan koleksi generik.Jenis referensi tidak mendapat manfaat sebanyak tetapi
IEquatable<T>
implementasi tidak membiarkan Anda menghindari para pemainSystem.Object
yang dapat membuat perbedaan jika sering dipanggil.Sebagaimana dicatat di blog Jared Parson , Anda masih harus mengimplementasikan penggantian Objek.
sumber
IEquatable<T>
antarmuka melakukan sesuatu selain mengingatkan pengembang untuk memasukkanpublic bool Equals(T other)
anggota dalam kelas atau struct? Ada atau tidak adanya antarmuka tidak membuat perbedaan saat dijalankan. KelebihanEquals
akan tampaknya semua yang diperlukan.Menurut MSDN :
Jadi sepertinya tidak ada perbedaan fungsional yang nyata antara keduanya kecuali bahwa keduanya dapat dipanggil tergantung pada bagaimana kelas digunakan. Dari sudut pandang kinerja, lebih baik menggunakan versi generik karena tidak ada penalti tinju / unboxing yang terkait dengannya.
Dari sudut pandang logis, lebih baik untuk mengimplementasikan antarmuka. Meng-override objek tidak benar-benar memberi tahu siapa pun bahwa kelas Anda sebenarnya setara. Override mungkin hanya kelas do nothing atau implementasi dangkal. Menggunakan antarmuka secara eksplisit mengatakan, "Hei, benda ini valid untuk pemeriksaan kesetaraan!" Itu hanya desain yang lebih baik.
sumber
Memperluas apa yang dikatakan Josh dengan contoh praktis. +1 ke Josh - Saya akan menulis hal yang sama dalam jawaban saya.
Dengan cara ini, saya memiliki metode Equals () yang dapat digunakan kembali yang bekerja di luar kotak untuk semua kelas turunan saya.
sumber
Jika kita menyebutnya
object.Equals
, itu memaksa untuk melakukan tinju mahal pada tipe nilai. Ini tidak diinginkan dalam skenario yang peka terhadap kinerja. Solusinya adalah menggunakanIEquatable<T>
.Gagasan di belakang
IEquatable<T>
adalah bahwa ia memberikan hasil yang samaobject.Equals
tetapi lebih cepat. Batasanwhere T : IEquatable<T>
harus digunakan dengan tipe generik seperti di bawah ini.jika tidak, itu mengikat
slower object.Equals()
.sumber