Какова цель Decimal.One, Decimal.Zero, Decimal.MinusOne в .Net - PullRequest
63 голосов
/ 14 апреля 2009

Простой вопрос - почему тип Decimal определяет эти константы? Зачем?

Я ищу причину, по которой это определяется языком, невозможным использованием или влиянием на компилятор. Зачем ставить это там в первую очередь? Компилятор может так же легко встроить 0m, как и Decimal.Zero, поэтому я не покупаю его как ярлык компилятора.

Ответы [ 4 ]

30 голосов
/ 14 апреля 2009

Небольшое уточнение. На самом деле они являются статическими значениями только для чтения, а не константами. Это имеет явное различие в .Net, поскольку постоянные значения встроены различными компиляторами, и, следовательно, невозможно отследить их использование в скомпилированной сборке. Статические значения только для чтения, однако, не копируются, а вместо этого ссылаются. Это полезно для вашего вопроса, потому что это означает, что их использование может быть проанализировано.

Если вы используете отражатель и копаете BCL, вы заметите, что MinusOne и Zero используются только во время выполнения VB. Он существует главным образом для обслуживания преобразований между десятичными и логическими значениями. Почему MinusOne используется по совпадению, возникла в отдельном потоке только сегодня ( ссылка )

Как ни странно, если вы посмотрите на значение Decimal.One, вы заметите, что оно нигде не используется.

Относительно того, почему они явно определены ... Я сомневаюсь, что есть веская и быстрая причина. Там , по-видимому, не имеет конкретной производительности и является лишь некоторой мерой удобства, которую можно отнести к их существованию. Мое предположение состоит в том, что они были добавлены кем-то во время разработки BCL для их удобства и просто никогда не удаляются.

EDIT

Вскочил в проблему const чуть больше после комментария @Paleta. Определение C # Decimal.One использует модификатор const, однако он излучается как static readonly на уровне IL. Компилятор C # использует несколько приемов, чтобы сделать это значение практически неотличимым от const (например, встроенные литералы). Это будет отображаться на языке, который распознает этот трюк (VB.Net распознает это, но F # нет).

19 голосов
/ 14 апреля 2009

Некоторые языки .NET не поддерживают десятичный тип данных, и в этих случаях удобнее (и быстрее) писать Decimal.ONE вместо нового Decimal (1).

Класс Java BigInteger также имеет ZERO и ONE, по той же причине.

0 голосов
/ 03 августа 2010

Эти 3 значения arghhh !!!

Я думаю, что они могут иметь какое-то отношение к тому, что я называю тянущимися 1 *

скажем, у вас есть эта формула:

(x) 1.116666 + (y) = (z) 2.00000

но x , z округлены до 0,11 и 2,00 , и вас попросят вычислить (y).

так что вы можете подумать y = 2.00 - 1.11. На самом деле y равно 0,88 , но вы получите 0,89 . (разница составляет 0,01 ).

Зависит от реального значения x и y, результаты будут варьироваться от -0.01 до + 0.01 , а в некоторых случаях при работе с кучей тех, кто тянется за 1, и чтобы облегчить вещи, вы можете проверить, равна ли конечная величина Decimal.MinusOne / 100, Decimal.One / 100 или Decimal.Zero / 100, чтобы исправить их.

Вот как я их использовал.

0 голосов
/ 14 апреля 2009

Мое мнение о том, что они существуют, чтобы помочь избежать магических чисел.

Магические числа в основном в любом месте вашего кода, где у вас есть число aribtrary. Например:

int i = 32;

Это проблематично в том смысле, что никто не может сказать , почему i устанавливается в 32, или что означает 32, или если это вообще должно быть 32. Это волшебно и таинственно.

В том же духе, я часто вижу код, который делает это

int i = 0;
int z = -1;

Почему они установлены на 0 и -1? Это просто совпадение? Они что-то значат? Кто знает?

Хотя Decimal.One, Decimal.Zero и т. Д. Не говорят вам, что значения означают в контексте вашего приложения (может быть, ноль означает «отсутствует» и т. Д.), Он действительно говорит вам, что значение было преднамеренно установлено и, вероятно, имеет некоторый смысл.

Хотя и не идеально, это гораздо лучше, чем вообще ничего вам не говорить: -)

Примечание Это не для оптимизации. Соблюдайте этот код C #:

public static Decimal d = 0M;
public static Decimal dZero = Decimal.Zero;

При просмотре сгенерированного байт-кода с помощью ildasm обе опции приводят к идентичным MSIL. System.Decimal является типом значения, поэтому Decimal.Zero не более «оптимален», чем просто использование литерального значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...