คำตอบสั้น ๆ :
ความเท่าเทียมกันนั้นซับซ้อน
คำตอบโดยละเอียด:
ชนิดพื้นฐานจะลบล้างฐานobject.Equals(object)
และคืนค่าจริงถ้ากล่องobject
นั้นเป็นประเภทและค่าเดียวกัน (โปรดทราบว่ามันจะใช้ได้กับประเภทที่สามารถลบได้ด้วยเช่นกันชนิดที่ไม่ใช่ค่า null จะเป็นกล่องสำหรับอินสแตนซ์ของประเภทพื้นฐาน)
เนื่องจากnewAge
เป็น a short
, Equals(object)
เมธอดของมันจะคืนค่าเป็นจริงถ้าคุณผ่านการย่อบ็อกซ์ด้วยค่าเดียวกัน คุณกำลังส่งกล่องint
แล้วมันจะส่งกลับเท็จ
ในทางตรงกันข้าม==
ผู้ปฏิบัติงานจะถูกกำหนดให้รับค่าสองint
s (หรือshort
s หรือlong
s)
เมื่อคุณเรียกมันด้วยint
a และ a short
คอมไพเลอร์จะแปลงค่าshort
เป็นint
และเปรียบเทียบผลลัพธ์int
s โดยค่า
วิธีอื่น ๆ ในการทำให้มันใช้งานได้
ประเภทดั้งเดิมมีEquals()
วิธีการของตนเองที่ยอมรับประเภทเดียวกัน
ถ้าคุณเขียนage.Equals(newAge)
คอมไพเลอร์จะเลือกint.Equals(int)
เป็นเกินที่ดีที่สุดและโดยปริยายแปลงไปshort
int
มันจะกลับมาtrue
เนื่องจากวิธีนี้จะเปรียบเทียบint
s โดยตรง
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