“十进制”来源$ C ​​$从微软Ç - 将它打造?微软、将它、来源、十进制

2023-09-03 03:19:40 作者:孤独症

最近我尝试回答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 :(