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

Types Decimal.MinValue&;Decimal.MaxValue:为什么是静态只读修饰符而不是常量修饰符?,types,static,constants,readonly,numeric,Types,Static,Constants,Readonly,Numeric,在C#中,MinValue字段是为具有以下内容的数字类型定义的: ① 静态只读十进制类型的修饰符: ② 常量所有其他数值类型的修饰符: //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

在C#中,MinValue字段是为具有以下内容的数字类型定义的:

静态只读十进制类型的修饰符:

常量所有其他数值类型的修饰符:

//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
为什么不使用常量修饰符定义Decimal.MinValue字段

备注:

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


② VB、C++和Fα也使用不同的修饰符,所以这个问题不属于C语言。

< P>这是一个有趣的问题。我做了一些研究,MS文档中关于
Decimal
Min/Max字段的明确说明(请注意,两者的措辞相同;为了清晰起见,显示在括号中):

该常数的值为[负]79228162514264337593543950335

以下代码编译时没有问题:

public const decimal MaxValue = 79228162514264337593543950335M;
-编辑- 注意:下面是.NET 4.5(从MS下载的PDB源代码)源代码中的字段赋值,该代码调用十进制构造函数。请注意,它正在声明一个常量值。至少对于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;
}
public const Decimal MinValue=new Decimal(-1,-1,-1,true,(字节)0);
public const Decimal MaxValue=new Decimal(-1,-1,-1,false,(字节)0);
公共十进制(整数低、整数中、整数高、布尔为负、字节刻度)
{
如果((整数)比例>28)
抛出新ArgumentOutOfRangeException(“scale”,Environment.GetResourceString(“ArgumentOutOfRange_DecimalScale”);
this.lo=lo;
this.mid=mid;
hi=hi;

this.flags=(int)scale我本以为这是为了源代码的可读性

public const Decimal MaxValue = new Decimal(-1, -1, -1, false, (byte) 0);
似乎比魔法数字更具可读性:

public const Decimal MaxValue = 79228162514264337593543950335m

首先,请注意,正如Jon Skeet在回答rmayer06的相关问题时提到的那样,从语言的角度(而不是CLR)来看,这些
Decimal
值被视为常量

(我认为使用
ReadOnly
而不是
Const
的原因是,在每次使用
Const
时都不会调用构造函数,除了:-()

如果在C#或VB.NET中编译:
x==Decimal.MaxValue
,则该常量的构造就像它实际上是一个
常量一样

在VB.NET中,对于
Decimal.One
Decimal.Zero
Decimal.MinusOne
,这是不正确的,但它们在C#中被视为常量。(顺便说一句
String.Empty
在这两种语言中都不被视为常量。)

所以我相信这些都是作为常量烘焙到语言中的(有时候,在VB的例子中)

在VB的情况下,它似乎更喜欢加载
只读
值,除了
MaxValue
Minvalue
(即
consty1为Decimal=Decimal.One
被VB有效地别名,但在C#中真正被视为常量。)

顺便说一句,MaxValue也是
只读的
,但VB.NET不将其视为常量(即使它有
日期
文字)

更新:我还没有检查最新的VB.NET或C的当前结果,但是参考源没有特别处理
Decimal.One
Decimal.Zero
Decimal.MinusOne
Decimal.MaxValue
Decimal.MinValue
中的任何一个;它们都是正确的。

虽然描述了Decimal
MinValue
字段作为
静态只读
,C#编译器将其视为
const

MinValue
字段是只读的,则下面的代码不会编译,但它确实编译

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

备注:

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

② 有关更多详细信息,Jon Skeet对IL级别的恒定现场实施在以下方面的差异进行了深入了解:

  • 基本数字类型(整数、浮点和双精度)和
  • 非原始数字十进制类型

Decimal
不像其他类型那样原始。请注意,(无论在源代码中需要什么技巧才能实现这一点),
Decimal
结构的
MinValue
字段是一个
常量,其行为与之类似。如果使用Visual Studio并使用“转到定义”(F12)在
decimal
上,您将看到“元数据”(通过反射从实际程序集生成的C#代码),它显示
[小数常量(0,128,4294967295,4294967295,4294967295)]public const decimal MinValue=-79228162514264337593543950335m;
。因此
MinValue
充当常量。您可以从中声明其他
const
值,将其用作可选参数的默认值,等等。@MarkHurd虽然这在.NET中是正确的,但在C#规范中,
decimal
i类型很重要它是语言中的预定义类型,在C中是所谓的简单类型,请参见和(这里我链接了规范的旧版本,但在最新版本中是相同的)。C允许所有这些“简单类型”的
const
字段,包括
decimal
。现在,当mscorlib包含“预定义类型”的源代码时,可能需要一些技巧。因此,实际上,这个问题不再相关,因为在实际代码中,它是一个
常量
,而不是文档中所述的
静态只读
。但是,兔子洞仍然相当深。为什么会有常量而不是只读,这是反编译器的问题吗?此代码不会使用const关键字goo编译d点-这必须是特定于版本的。2.0框架明确指出
public const Decimal MaxValue=79228162514264337593543950335m;
不可能在代码中使用它
public const Decimal MaxValue = 79228162514264337593543950335m