Definition of “==” operator for Double

前端 未结 5 615
萌比男神i
萌比男神i 2020-12-23 08:38

For some reason I was sneaking into the .NET Framework source for the class Double and found out that the declaration of == is:

public static bo         


        
5条回答
  •  醉酒成梦
    2020-12-23 09:08

    In reality, the compiler will turn the == operator into a ceq IL code, and the operator you mention will not be called.

    The reason for the operator in the source code is likely so it can be called from languages other than C# that do not translate it into a CEQ call directly (or through reflection). The code within the operator will be compiled to a CEQ, so there is no infinite recursion.

    In fact, if you call the operator via reflection, you can see that the operator is called (rather than a CEQ instruction), and obviously is not infinitely recursive (since the program terminates as expected):

    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}));
    

    Resulting IL (compiled by 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 
    

    Interestingly - the same operators do NOT exist (either in the reference source or via reflection) for integral types, only Single, Double, Decimal, String, and DateTime, which disproves my theory that they exist to be called from other languages. Obviously you can equate two integers in other languages without these operators, so we're back to the question "why do they exist for double"?

提交回复
热议问题