双重暗示的目的是什么?

例如:

const decimal dollars = 25.50M; 

为什么我们要加M

为什么不这样做:

 const decimal dollars = 25.50; 

因为它已经说decimal ,这不意味着25.50是小数吗?

没有。

25.50double类型的独立表达式,而不是decimal
编译器不会看到您尝试将其分配给decimal变量并将其解释为十进制。

除了lambda表达式,匿名方法和条件运算符之外,所有C#表达式都有一个完全不依赖于上下文的固定类型。

想象一下,如果编译器按你想要的那样会发生什么,你调用了Math.Max(1, 2)
Math.Max具有带intdoubledecimal重载。 它会叫哪一个?

在这种情况下,有两个重要的概念需要理解。

  1. 文字价值观
  2. 隐式转换

基本上你要问的是文字值是否可以在两种类型之间隐式转换。 在没有精度损失的情况下,编译器实际上会为您执行此操作。 以此为例:

 long n = 1000; // Assign an Int32 literal to an Int64. 

这是可能的,因为long (Int64)与int (Int32)相比包含更大范围的值。 对于您的具体示例,可能会失去精度。 以下是decimaldouble精度的完全不同的范围。

十进制:±1.0×10 -28到±7.9×10 28
双倍:±5.0×10 -324至±1.7×10 308

有了知识,很明显为什么隐式转换是个坏主意。 以下是C#编译器当前支持的隐式转换列表。 我强烈建议你做一些关于这个问题的轻读。

隐式数字转换表

另请注意,由于定义了双精度和小数的内部细节,您的分配或计算中可能会出现轻微的舍入错误。 您需要知道浮点数,双精度数和小数数如何在位级工作,以始终做出最佳选择。

例如,double不能精确地存储值25.10,但是十进制可以。

双精度可以精确地存储值25.50,但是出于有趣的二进制编码原因。

十进制结构