Подтвердить что ты не робот

Какова цель Decimal.One, Decimal.Zero, Decimal.MinusOne в .Net

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

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

4b9b3361

Ответ 1

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

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

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

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

ИЗМЕНИТЬ

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

Ответ 2

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

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

Ответ 3

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

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

int i = 32;

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

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

int i = 0;
int z = -1;

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

В то время как Decimal.One, Decimal.Zero и т.д. не сообщают вам, что означают значения в контексте вашего приложения (возможно, нуль означает "отсутствует" и т.д.), он говорит вам, что значение было намеренно установлено, и, вероятно, имеет некоторое значение.

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

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

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

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

Ответ 4

Те 3 значения arghhh!!!

Я думаю, что они могут иметь какое-то отношение к тому, что я называю trailing 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, а в некоторых случаях при работе с кучей тех, и для удобства вещей вы можете проверить, соответствует ли конечное значение Decimal.MinusOne / 100, Decimal.One / 100 или Decimal.Zero / 100, чтобы исправить их.

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