Decimal.MinValue & Decimal.MaxValue: почему статические readonly, а не const-модификаторы?
В C# поле MinValue определено для числовых типов с помощью:
① статические модификаторы только для чтения для десятичного типа (ссылка на MSDN Libray для.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 ответа
Хотя библиотека MSDN описывает десятичную MinValue
поле как бытие static readonly
Компилятор C# рассматривает это как const
,
Если MinValue
Поле было только для чтения, следующий код не будет компилироваться, но на самом деле он компилируется.
const decimal test = decimal.MinValue - decimal.MinValue;
Замечания:
① Тот же ответ относится к десятичному типу MaxValue
поле.
② Для получения более подробной информации Джон Скит дает здесь представление о том, как постоянная полевая реализация на уровне IL отличается между:
- Примитивные числовые типы (целые числа, числа с плавающей запятой и двойные числа) и
- Непримитивный числовой десятичный тип.
Это интересный вопрос. Я провел некоторое исследование и документацию MS по Decimal
Мин / Макс поля явно говорит (обратите внимание, что формулировки одинаковы для обоих; для ясности показаны в скобках):
Значение этой константы равно [отрицательно] 79,228,162,514,264,337,593,543,950,335.
Следующий код компилируется без проблем:
public const decimal MaxValue = 79228162514264337593543950335M;
- Редактировать -
Примечание: вот назначение поля из источника для.NET 4.5 (загруженный источник PDB из MS), десятичный конструктор, который вызывается этим кодом. Обратите внимание, что он объявляет постоянное значение. Кажется, по крайней мере для 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;
Таким образом, несоответствие и неправильная документация - это вывод, к которому я пришел. Я оставлю это другим, чтобы посмотреть на другие версии фреймворка для шаблона.
Во-первых, обратите внимание, что эти Decimal
значения рассматриваются как константы с точки зрения языков (но не CLR), как упоминает Джон Скит в своем ответе на вопрос, связанный с rmayer06.
(Я думал причина использования ReadOnly
вместо Const
было так, что конструктор не вызывался при каждом использовании Const
кроме того, что есть:-()
Если вы компилируете: x == Decimal.MaxValue
в C# или VB.NET константа создается так, как если бы она была Const
,
В VB.NET это не так для Decimal.One
, Decimal.Zero
или же Decimal.MinusOne
, но они рассматриваются как константы в C#. (BTW String.Empty
не рассматривается как константа ни на одном языке.)
Так что я считаю, что они встраиваются в языки как константы (иногда, в случае VB).
В случае VB, кажется, предпочитает загружать ReadOnly
значения, кроме MaxValue
, а также Minvalue
, (То есть Const y1 As Decimal = Decimal.One
эффективно псевдоним VB, но действительно рассматривается как константа в C#.)
КСТАТИ Date.MaxValue
это также ReadOnly
, но VB.NET не считает его константой (хотя он Date
литералы).
ОБНОВЛЕНИЕ: я не проверял, каковы текущие результаты для самых последних VB.NET или C#, но справочный источник не обрабатывает ни один из Decimal.One
, Decimal.Zero
, Decimal.MinusOne
, Decimal.MaxValue
или же Decimal.MinValue
специально; они все просто public const
,
Я бы подумал, что это было для удобочитаемости исходного кода
public const Decimal MaxValue = new Decimal(-1, -1, -1, false, (byte) 0);
кажется более читабельным, чем магическое число:
public const Decimal MaxValue = 79228162514264337593543950335m