gpt4 book ai didi

c# - Double 的 "=="运算符的定义

转载 作者:IT王子 更新时间:2023-10-29 03:33:23 25 4
gpt4 key购买 nike

出于某种原因,我潜入了 Double 类的 .NET Framework 源代码中并发现 == 的声明是:

public static bool operator ==(Double left, Double right) {
return left == right;
}

相同的逻辑适用于每个 运算符。


  • 这样的定义有什么意义?
  • 它是如何运作的?
  • 为什么它不创建无限递归?

最佳答案

实际上,编译器会将==运算符变成ceq IL代码,而不会调用您提到的运算符。

源代码中运算符的原因可能是可以从 C# 以外的语言调用它,这些语言不会直接(或通过反射)将其转换为 CEQ 调用。运算符的代码编译为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

有趣的是 - 整数类型不存在相同的运算符(无论是在引用源中还是通过反射),只有 SingleDoubleDecimalStringDateTime,这反驳了我的理论,即它们的存在是为了从其他语言调用。显然,您可以在没有这些运算符的情况下用其他语言将两个整数等同起来,所以我们回到“为什么它们存在于 double”这个问题上?

关于c# - Double 的 "=="运算符的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35133777/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com