Decimal.MinValue& Decimal.MaxValue:为什么静态只读而不是const修饰符?

时间:2014-02-01 17:45:14

标签: types static const readonly numeric

在C#中, MinValue 字段是为数字类型定义的:

静态只读十进制类型(Link to MSDN Libray for .NET 4.5)的修饰符:

public static readonly decimal MinValue

②所有其他数字类型的 const 修饰符:

//Integral signed numeric types
public const sbyte MinValue
public const short MinValue
public const int MinValue
public const long MinValue

//Integral unsigned numeric types
public const byte MinValue
public const ushort MinValue
public const uint MinValue
public const ulong MinValue

//Real numeric types
public const float MinValue
public const double MinValue

为什么 const 修饰符不用于定义Decimal.MinValue字段?

说明

①同样的问题适用于数字类型 MaxValue 字段。

②VB,C ++和F#也对十进制类型使用不同的修饰符,所以这个问题不是特定于C#语言。

4 个答案:

答案 0 :(得分:1)

这是一个有趣的问题。我做了一些研究,Decimal最小/最大字段的MS文档明确说明(注意两者的措辞相同;为清楚起见,括号内显示):

  

此常数的值为[负] 79,228,162,514,264,337,593,543,950,335。

以下代码编译没有问题:

public const decimal MaxValue = 79228162514264337593543950335M;

- 编辑 -

注意:这里是从.NET 4.5的源代码(从MS下载的PDB源)中分配字段,这是由此代码调用的十进制构造函数。请注意,它声明了一个const值。至少4.5版似乎是文档错误。 (这不是MS文档第一次不正确)。如@Daniel的评论中所指出的,源代码似乎也不会编译。

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;
}

另请注意:在2.0框架中,十进制是直接声明的:

public const Decimal MaxValue = 79228162514264337593543950335m;

因此,不一致和不正确的文档是我达成的结论。我将把它留给其他人来查看模式的其他框架版本。

答案 1 :(得分:1)

首先,请注意,这些Decimal 从语言的角度(而不是CLR)看作常量,正如Jon Skeet在his answer中提到的那样rmayer06的相关问题。

(我认为使用ReadOnly代替Const的原因是每次使用Const时都没有调用构造函数,除了是:-()

如果你在C#或VB.NET中编译:{{1​​}},那么常量被构造成好像它真的是x == Decimal.MaxValue

在VB.NET中,ConstDecimal.OneDecimal.Zero为true,但这些 被视为常量在C#中。 (BTW Decimal.MinusOne在任何一种语言中都不被视为常数。)

所以我相信这些都是作为常量加入到语言中(有时候,在VB的情况下)。

在VB的情况下, 似乎更喜欢加载String.Empty值,ReadOnlyMaxValue除外。 (那是Minvalue实际上是由VB别名,但在C#中真正被视为常量。)

BTW Const y1 As Decimal = Decimal.One也是Date.MaxValue,但它是被VB.NET视为常量(即使它确实有ReadOnly个文字)。

更新:我没有检查最新的VB.NET或C#的当前结果,但参考源不会处理DateDecimal.OneDecimal.Zero中的任何一个,Decimal.MinusOneDecimal.MaxValue特别;他们都只是public const

答案 2 :(得分:1)

虽然MSDN library将小数MinValue字段描述为static readonly,但C#编译器将其视为const

如果MinValue字段是只读的,则以下代码无法编译,但实际上确实编译

const decimal test = decimal.MinValue - decimal.MinValue;

说明

①相同的答案适用于十进制类型MaxValue字段。

②有关详细信息,Jon Skeet给出了here对IL级别的常量字段实现如何不同的见解:

  • 原始数字类型(积分,浮点数和双精度)和
  • 非原始数字十进制类型。

答案 3 :(得分:0)

我认为这是为了源代码的可读性

public const Decimal MaxValue = new Decimal(-1, -1, -1, false, (byte) 0);

似乎比幻数更具可读性:

public const Decimal MaxValue = 79228162514264337593543950335m