คำตอบสั้น ๆ :
ความเท่าเทียมกันนั้นซับซ้อน
คำตอบโดยละเอียด:
ชนิดพื้นฐานจะลบล้างฐานobject.Equals(object)และคืนค่าจริงถ้ากล่องobjectนั้นเป็นประเภทและค่าเดียวกัน (โปรดทราบว่ามันจะใช้ได้กับประเภทที่สามารถลบได้ด้วยเช่นกันชนิดที่ไม่ใช่ค่า null จะเป็นกล่องสำหรับอินสแตนซ์ของประเภทพื้นฐาน)
เนื่องจากnewAgeเป็น a short, Equals(object)เมธอดของมันจะคืนค่าเป็นจริงถ้าคุณผ่านการย่อบ็อกซ์ด้วยค่าเดียวกัน คุณกำลังส่งกล่องintแล้วมันจะส่งกลับเท็จ
ในทางตรงกันข้าม==ผู้ปฏิบัติงานจะถูกกำหนดให้รับค่าสองints (หรือshorts หรือlongs)
เมื่อคุณเรียกมันด้วยinta และ a shortคอมไพเลอร์จะแปลงค่าshortเป็นintและเปรียบเทียบผลลัพธ์ints โดยค่า
วิธีอื่น ๆ ในการทำให้มันใช้งานได้
ประเภทดั้งเดิมมีEquals()วิธีการของตนเองที่ยอมรับประเภทเดียวกัน
ถ้าคุณเขียนage.Equals(newAge)คอมไพเลอร์จะเลือกint.Equals(int)เป็นเกินที่ดีที่สุดและโดยปริยายแปลงไปshort intมันจะกลับมาtrueเนื่องจากวิธีนี้จะเปรียบเทียบints โดยตรง
shortยังมีshort.Equals(short)วิธีการ แต่intไม่สามารถแปลงเป็นโดยปริยายshortดังนั้นคุณไม่ได้เรียกมัน
คุณสามารถบังคับให้เรียกวิธีนี้โดยใช้นักแสดง:
Console.WriteLine(newAge.Equals((short)age)); // true
วิธีนี้จะโทรshort.Equals(short)โดยตรงโดยไม่ต้องชกมวย หากageมีขนาดใหญ่กว่า 32767 จะเป็นการยกเว้นข้อยกเว้นมากเกินไป
คุณสามารถเรียกshort.Equals(object)โอเวอร์โหลดได้ แต่ผ่านวัตถุที่บรรจุอยู่ในกล่องอย่างชัดเจนเพื่อให้ได้ชนิดเดียวกัน:
Console.WriteLine(newAge.Equals((object)(short)age)); // true
shortเช่นเดียวกับทางเลือกที่ก่อนหน้านี้จะโยนล้นถ้ามันไม่พอดีใน แตกต่างจากโซลูชันก่อนหน้านี้มันจะบรรจุshortลงในวัตถุเสียเวลาและหน่วยความจำ
รหัสแหล่งที่มา:
นี่คือทั้งสองEquals()วิธีจากซอร์สโค้ดจริง:
public override bool Equals(Object obj) {
if (!(obj is Int16)) {
return false;
}
return m_value == ((Int16)obj).m_value;
}
public bool Equals(Int16 obj)
{
return m_value == obj;
}
อ่านเพิ่มเติม:
ดูเอริค Lippert