最近我尝试回答a问题是用户发布的关于为什么十进制
结构没有声明其最大/最小值为常量
像其他数字的原始;相反,微软文档指出这是静态只读。
I was recently attempting to answer a question that a user posted about why the decimal
struct does not declare its Min/Max values as const
like every other numeric primitive; rather, the Microsoft documentation states that it is static readonly.
在研究,我挖通过Microsoft源$ C $ C,并想出了一个有趣的发现;源(.NET 4.5),使它看起来像一个常量
这是在反对什么,文件中明确规定(来源及相关结构构造粘贴下面)。
In researching that, I dug through the Microsoft source code, and came up with an interesting discovery; the source (.NET 4.5) makes it look like a const
which is in opposition to what the documentation clearly states (source and relevant struct constructor pasted below).
public const Decimal MinValue = new Decimal(-1, -1, -1, true, (byte) 0);
public const Decimal MaxValue = new Decimal(-1, -1, -1, false, (byte) 0);
public Decimal(int lo, int mid, int hi, bool isNegative, byte scale)
{
if ((int) scale > 28)
throw new ArgumentOutOfRangeException("scale", Environment.GetResourceString("ArgumentOutOfRange_DecimalScale"));
this.lo = lo;
this.mid = mid;
this.hi = hi;
this.flags = (int) scale << 16;
if (!isNegative)
return;
this.flags |= int.MinValue;
}
线程这里继续解开,因为我看不出这将依法编译在C#的规则 - 因为虽然它仍然是的技术上的常量,编译器认为是不并给你一个错误的EX pression被分配到......必须是常量
。因此,我认为是,文档称之为静态只读
。
The thread here continues to unravel, because I can't see how this would compile legally under the rules of C# - because while it still is technically a constant, the compiler thinks it isn't and will give you an error The expression being assigned to ... must be constant
. Hence what I believe is the reason that the docs call it a static readonly
.
现在,这引出了一个问题:从微软源服务器文件的实际上的来源为小数,或者已经是被篡改?我失去了一些东西?
Now, this begs a question: is this file from the Microsoft source server actually the source for decimal, or has it been doctored? Am I missing something?
有mscorlib中的一些方面并不会编译为编写的,没有一些有趣的黑客等。特别是,也有一些循环依赖。这是另一种情况,但我认为这是合理的考虑的MaxValue
和 MINVALUE
作为常量
至于C#编译器而言。
There are a few aspects of mscorlib and the like which wouldn't compile as-written, without some interesting hacks. In particular, there are some cyclic dependencies. This is another case, but I think it's reasonable to consider MaxValue
and MinValue
as being const
as far as the C# compiler is concerned.
在特别,它是有效的,以中的其他常量
计算使用它们:
In particular, it's valid to use them within other const
calculations:
const decimal Sum = decimal.MaxValue + decimal.MinValue;
中的字段具有DecimalConstantAttribute适用于他们,这实际上是一个黑客绕过C#和CLR之间的阻抗不匹配:你不能在CLR类型十进制
的恒定场你可以键入 INT
或字符串
,恒定的场,使用静态文字... 。
The fields have the DecimalConstantAttribute
applied to them, which is effectively a hack to get around an impedance mismatch between C# and the CLR: you can't have a constant field of type decimal
in the CLR in the same way that you can have a constant field of type int
or string
, with an IL declaration using static literal ...
.
(这也是为什么你不能在属性构造器中使用十进制
值 - 那里,常量性的要求是真实的IL-级常量性)
(This is also why you can't use decimal
values in attribute constructors - there, the "const-ness" requirement is true IL-level constness.)
相反,任何常量十进制
的声明在C#code编译成一个静态initonly
字段 DecimalConstantAttribute
适用于它指定相应的数据。 C#编译器使用该信息来对待这样一个字段作为一个恒定的前pression其他地方。
Instead, any const decimal
declaration in C# code is compiled to a static initonly
field with DecimalConstantAttribute
applied to it specifying the appropriate data. The C# compiler uses that information to treat such a field as a constant expression elsewhere.
基本上,十进制
的CLR是不是被称为原始式的方式, INT
, 浮动
等都是。有没有十进制
特异性IL指令。
Basically, decimal
in the CLR isn't a "known primitive" type in the way that int
, float
etc are. There are no decimal
-specific IL instructions.
现在,在具体的C#code你指的条款,我怀疑有两种可能:
Now, in terms of the specific C# code you're referring to, I suspect there are two possibilities:
不,这是不准确的源$ C $ C使用。 用于编译mscorlib程序和框架等核心方面可能有应用允许此类code特殊标志,直接将其转换为C#编译器 DecimalConstantAttribute
在很大程度上,你可以忽略这一点 - 它不会影响你。这是一个耻辱,MSDN文档中的字段作为静态只读
,而不是常量
虽然,因为这给了错误的IM pression,人们可以不使用它们的常量
EX pressions:(
To a large extent you can ignore this - it won't affect you. It's a shame that MSDN documents the fields as being static readonly
rather than const
though, as that gives the mistaken impression that one can't use them in const
expressions :(