Pertanyaan Mengapa operator == (didefinisikan untuk tipe beton) tidak digunakan?


Saya memiliki daftar yang didefinisikan sebagai:

var Items = new List<IItem>();

Sekarang ada sejumlah kelas berbeda yang memiliki antarmuka itu dan salah satunya adalah Consumable. Kelas yang Dikonsumsi juga memiliki operator == kelebihan beban. Sekarang saya memiliki kode berikut dan tidak berfungsi:

if(item1 == item2)
{
    //code...
}

Ini tidak bekerja. Saya menempatkan titik istirahat di operator == kelebihan dan tidak pernah sampai ke sana. Ketika saya melakukan debugging baris-demi-baris, baik item1 dan item2 adalah tipe Consumable, keduanya GetType returns Consumable. Saya bahkan mencoba kode ini:

var temp = item1.GetType();
var temp2 = item2.GetType();
if (temp == temp2)
{
    //code...
}

dan hasil kesetaraan ini benar. Sekarang jika saya mencoba ini:

if(((Consumable)item1) == ((Consumable)item2))
{
    //code...
}

dan ini memicu break point pada operator == yang berlebihan. Mengapa saya harus secara manual mentransmisikan variabel jika ketika line-by-line debugging menunjukkan itu sudah menganggap mereka sama-sama habis? Apakah karena saya menarik mereka dari daftar IItems?


4
2018-04-27 11:48


asal


Jawaban:


Karena daftar Anda List<IItem>, Saya mengasumsikan Anda memiliki sesuatu seperti:

var item1 = Items[0];

atau terserah; sini item1  variabel diketik sebagai IItem. Resolusi operator terjadi selama membangun melalui analisis statis (tidak saat runtime melalui polimorfisme / RTTI), jadi satu-satunya == tersedia adalah default untuk apa pun object, yaitu persamaan referensi.

Untuk mendukung operator kustom Anda, variabel harus diketik sesuai, misalnya:

Consumable item1 = ..., item2 = ...;

Pemeran Anda mencapai hal yang sama.

Pilihan lain adalah memastikannya == dan Equals (dan GetHashCode()) setuju, dan gunakan:

if(Equals(item1, item2)) {...}

yang akan dilakukan null cek dan kemudian gunakan overridden Anda Equals metode. Ini kemudian mendukung polimorfisme, jadi tidak masalah apa jenisnya.


10
2018-04-27 11:51



Runtime langauge umum hanya mengetahui bahwa dua objek Anda mengimplementasikan antarmuka IItem. Bagian umum terkecil dalam hierarki objek adalah System.Object. Dan Anda tidak membebani operator == System.Object.

Untuk menggunakan kelebihan beban yang benar Anda harus menyatakan jenis objek.


1
2018-04-27 11:52



== tidak memeriksa persamaan jenis, tetapi untuk kelas itu memeriksa kesetaraan referensi. Jadi, jika variabel menunjuk ke objek yang sama itu akan benar. Misalnya seperti ini:

var temp = item1;
var temp2 = item1;

if( temp == temp2 )
{
  //this code will execute
}

0
2018-04-27 11:51



Bukankah seharusnya IItem IComparable?


0
2018-04-27 11:53