.Net中Decimal.One,Decimal.Zero,Decimal.MinusOne的用途是什么


73

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

我正在寻找为什么这是由语言定义的原因,而不是对编译器的可能用途或影响。为什么首先要放在这里?编译器可以像Decimal.Zero一样轻松地插入0m,因此我不打算将其作为编译器快捷方式购买。


2
我认为这些答案不足以解释为什么存在这些价值观。我听到了一些效果和用法,但是我要寻找的是为什么要将此语言设计成这种语言,以及为什么它不在Float或Int32中?
Jasmine

它们帮助编译器生成更紧凑的程序集。今天
Hans Passant

Answers:


35

小澄清。它们实际上是静态只读值,而不是常量。.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#不能识别)。


这些值是只读的是不正确的,查看.net框架的Decimal元数据,您会看到以下[DecimalConstant(0,0,4294967295,4294967295,4294967295)] public const decimal MaxValue = 79228162514264337593543950335m; [DecimalConstant(0,128,0,0,1)]公共常量十进制MinusOne = -1m;
Paleta 2011年

@Paleta,不,他们是readonly。我已经通过查看元数据和MSDN页面中的hte值来验证了这一点。 msdn.microsoft.com/zh-CN/library/system.decimal.one(VS.80).aspx
JaredPar

我不同意您和您的回答,请在此处查看反射的mscorlib.dll代码reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10 / ...那些声明为常量,MSDN是错误
Paleta

1
好吧,我刚刚看到在IL上将其声明为字段static initonly,C#中的所有const是否都转换为静态readonly字段?感谢您的澄清
Paleta

2
@Paleta我和您一样感到困惑。我不得不坐下来几分钟,并处理生成的IL和C#源代码,以了解此处发生的情况。不过,对于您的问题,大多数C#常量都不以.literal值的形式发出。似乎只有DateTimeDecimal在该混合方式发射
JaredPar

22

某些.NET语言不支持十进制文字,在这种情况下,编写Decimal.ONE而不是新的Decimal(1)更加方便(并且更快)。

出于相同的原因,Java的BigInteger类也具有ZERO和ONE。


1
谁可以给我解释一下这个?6票赞成意味着它必须是一个很好的答案-但是:不支持将十进制作为数据类型的.Net语言如何从共享的只读属性(该属性返回十进制并定义为十进制的一部分)中受益类?
Rob P.

8
他可能的意思是,如果一种语言没有十进制文字,那么使用常量比将int文字转换为十进制会更有效。每种.NET语言都支持System.Decimal数据类型,它是CLR的一部分。
Niki

1
是的,Niki我想说的是 您当然可以在所有.NET语言中使用System.Decimal,但是有些支持它更好(例如C#具有十进制关键字和十进制文字),而有些则更糟。抱歉,英语不是我的母语……
mihi

谢谢你的解释。现在这很有意义。
罗布P.

0

我对此的看法是,它们在那里可以避免出现幻数。

幻数基本上是代码中随处可见的数字。例如:

int i = 32;

从没有人知道我为什么设置为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没有比仅使用文字值更“最优”的了。


你的论点伤了我的头。它们是数字,只有在您开始对数字赋予随机含义时,它们才会变成魔术数字,例如-1表示洗碗而1表示烤蛋糕。小数:1与1一样神奇,但可以说更难阅读(但也许更理想)。
Fuzzy-waffle

我的观点是,如果有人键入Decimal.Zero,则他们更有可能故意这样做,因为Zero具有某些含义-而不是随意将其设置为0
Orion Edwards 2009年

我认为将某些内容分配给0是任意的。对于将符号常量映射到数字的枚举是有意义的,但是对于映射到数字的数字来说似乎很疯狂。有时0确实是...零。另一方面,单位将是一个很好的构造。!1公里= 1
模糊-华夫

5
说Decimal.Zero就像说0.0一样随意。如果我们谈论的是在操作系统级别上发生更改的内容,例如“ /”与描述文件系统分隔符的某些库常量,那是有道理的,但Decimal.Zero始终仅为0.0。
本森

6
该死的,这只是我的意见。我以为我说清楚了:-(
Orion Edwards

-6

那三个值啊!

我认为他们可能与我称之为尾随1的东西有关

说你有这个公式:

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

但是xz会四舍五入为0.112.00,并且要求您计算(y)。

所以你可能会想y = 2.00 - 1.11。实际上y等于0.88,但您将获得0.89。(相差0.01)。

主要依靠X的真正价值和y将改变从结果-0.01+0.01,在某些情况下与一群那些尾随的1的交易时,并facilate东西,你可以检查是否尾随值等于Decimal.MinusOne / 100Decimal.One / 100Decimal.Zero / 100修复它们。

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


5
你在说什么?您正在使用不精确的值进行错误的数学运算,然后使用除法运算符得出您的epsilon吗?是什么让您认为结果总是精确地偏离0.01,而不是(例如)0.005?如果这些值代表金钱,那么我不敢与您的应用程序打交道。
丹尼尔·普里登

:)我没有计算最终结果,我必须为四舍五入格式提供(y)的值。你会怎么做?
哈森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.