74

简单的问题 - 为什么 Decimal 类型定义这些常量?何苦?

我正在寻找为什么这是由语言定义的原因,而不是对编译器的可能用途或影响。为什么一开始就把这个放在那里?编译器可以像 Decimal.Zero 一样轻松地内联 0m,所以我不购买它作为编译器快捷方式。

4

4 回答 4

38

小澄清。它们实际上是静态只读值而不是常量。这在 .Net 中有明显的区别,因为常量值由各种编译器内联,因此无法在编译的程序集中跟踪它们的使用。然而,静态只读值不会被复制,而是被引用。这对您的问题有利,因为这意味着可以分析它们的使用。

如果您使用反射器并深入研究 BCL,您会注意到 MinusOne 和 Zero 仅在 VB 运行时中使用。它主要用于服务十进制和布尔值之间的转换。为什么使用 MinusOne 恰好在今天出现在一个单独的线程上(链接

奇怪的是,如果您查看 Decimal.One 值,您会发现它在任何地方都没有使用。

至于为什么明确定义它们......我怀疑有一个硬性和快速的原因。似乎没有具体的表现,只有一点点方便的措施可以归因于它们的存在。我的猜测是,它们是在 BCL 开发过程中为了方便而被某人添加的,并且从未被删除。

编辑

const在@Paleta 发表评论后,深入研究了这个问题。的 C# 定义Decimal.One使用const修饰符,但是它static readonly在 IL 级别作为 a 发出。C# 编译器使用了一些技巧来使这个值与 a 几乎无法区分const(例如内联文字)。这将出现在一种能够识别这个技巧的语言中(VB.Net 能识别这一点,但 F# 不能)。

于 2009-04-13T22:30:29.643 回答
24

一些 .NET 语言不支持十进制文字,在这些情况下,编写 Decimal.ONE 而不是 new Decimal(1) 更方便(也更快)。

出于同样的原因,Java 的 BigInteger 类也有零和一。

于 2009-04-13T22:26:03.303 回答
-1

我对此的看法是,它们的存在是为了帮助避免幻数。

幻数基本上在您的代码中的任何地方,您有一个任意数字浮动。例如:

int i = 32;

这是有问题的,因为没有人知道为什么i 被设置为 32,或者 32 表示什么,或者它是否应该是 32。它神奇而神秘。

同样,我会经常看到执行此操作的代码

int i = 0;
int z = -1;

为什么将它们设置为 0 和 -1?这只是巧合吗?他们有什么意思吗?谁知道?

虽然Decimal.One,Decimal.Zero等不会告诉您值在应用程序上下文中的含义(可能零表示“丢失”等),但它确实告诉您该值是故意设置的,并且可能具有某些含义。

虽然并不完美,但这总比什么都不告诉你要好得多:-)

注意不是 为了优化。观察这个 C# 代码:

public static Decimal d = 0M;
public static Decimal dZero = Decimal.Zero;

使用 ildasm 查看生成的字节码时,两个选项都会产生相同的MSIL。System.Decimal是一种值类型,因此Decimal.Zero并不比仅使用文字值更“最佳”。

于 2009-04-13T22:23:43.183 回答
-6

那三个值啊啊啊!!!

我认为它们可能与我所说的尾随 1有关

说你有这个公式:

(x)1.116666 + (y) = (z)2.00000

但是x , z被四舍五入为0.112.00,你被要求计算 (y)。

所以你可能会想y = 2.00 - 1.11。实际上y等于0.88但你会得到0.89。(有0.01的差异)。

取决于 x 和 y 的实际值,结果将在-0.01+0.01之间变化,在某些情况下,在处理一堆尾随 1 时,为了方便起见,您可以检查尾随值是否等于Decimal.MinusOne / 100Decimal.One / 100Decimal.Zero / 100修复它们。

这就是我使用它们的方式。

于 2010-08-02T23:38:39.633 回答