ในความเป็นจริงคอมไพเลอร์จะเปลี่ยน==
โอเปอเรเตอร์ให้เป็นceq
รหัส IL และตัวดำเนินการที่คุณพูดถึงจะไม่ถูกเรียก
สาเหตุของโอเปอเรเตอร์ในซอร์สโค้ดนั้นน่าจะเรียกได้ว่ามาจากภาษาอื่นที่ไม่ใช่ C # ซึ่งไม่ได้แปลเป็นการCEQ
โทรโดยตรง (หรือผ่านการสะท้อนกลับ) โค้ดภายในตัวดำเนินการจะถูกคอมไพล์เป็น a CEQ
ดังนั้นจึงไม่มีการเรียกซ้ำไม่สิ้นสุด
ในความเป็นจริงหากคุณเรียกตัวดำเนินการผ่านการสะท้อนคุณจะเห็นว่าตัวดำเนินการถูกเรียก (แทนที่จะเป็นCEQ
คำสั่ง) และเห็นได้ชัดว่าไม่มีการวนซ้ำอย่างไม่มีที่สิ้นสุด (เนื่องจากโปรแกรมสิ้นสุดตามที่คาดไว้):
double d1 = 1.1;
double d2 = 2.2;
MethodInfo mi = typeof(Double).GetMethod("op_Equality", BindingFlags.Static | BindingFlags.Public );
bool b = (bool)(mi.Invoke(null, new object[] {d1,d2}));
ผลลัพธ์ IL (รวบรวมโดย LinqPad 4):
IL_0000: nop
IL_0001: ldc.r8 9A 99 99 99 99 99 F1 3F
IL_000A: stloc.0 // d1
IL_000B: ldc.r8 9A 99 99 99 99 99 01 40
IL_0014: stloc.1 // d2
IL_0015: ldtoken System.Double
IL_001A: call System.Type.GetTypeFromHandle
IL_001F: ldstr "op_Equality"
IL_0024: ldc.i4.s 18
IL_0026: call System.Type.GetMethod
IL_002B: stloc.2 // mi
IL_002C: ldloc.2 // mi
IL_002D: ldnull
IL_002E: ldc.i4.2
IL_002F: newarr System.Object
IL_0034: stloc.s 04 // CS$0$0000
IL_0036: ldloc.s 04 // CS$0$0000
IL_0038: ldc.i4.0
IL_0039: ldloc.0 // d1
IL_003A: box System.Double
IL_003F: stelem.ref
IL_0040: ldloc.s 04 // CS$0$0000
IL_0042: ldc.i4.1
IL_0043: ldloc.1 // d2
IL_0044: box System.Double
IL_0049: stelem.ref
IL_004A: ldloc.s 04 // CS$0$0000
IL_004C: callvirt System.Reflection.MethodBase.Invoke
IL_0051: unbox.any System.Boolean
IL_0056: stloc.3 // b
IL_0057: ret
ที่น่าสนใจ - ผู้ประกอบการเดียวกันไม่อยู่ (ทั้งในแหล่งอ้างอิงหรือผ่านการสะท้อน) ประเภทหนึ่งเท่านั้นSingle
, Double
, Decimal
, String
และDateTime
ซึ่งหักล้างทฤษฎีของฉันที่พวกเขามีอยู่จะเรียกว่ามาจากภาษาอื่น ๆ เห็นได้ชัดว่าคุณสามารถหาจำนวนเต็มสองจำนวนในภาษาอื่น ๆ ได้โดยไม่ต้องใช้ตัวดำเนินการเหล่านี้ดังนั้นเราจึงกลับไปที่คำถาม "ทำไมจึงมีอยู่double
"