Какой тип данных лучше всего использовать для денег в С#?
Какой тип данных лучше всего использовать для денег в С#?
Ответ 1
Как описано в decimal как:
Ключевое слово decimal указывает 128-битный тип данных. В сравнении с типы с плавающей точкой, десятичный тип имеет большую точность и меньший диапазон, что делает его подходящим для финансового и денежногорасчеты.
Вы можете использовать десятичную дробь следующим образом:
decimal myMoney = 300.5m;
Ответ 2
Тип десятичного значения представляет собой десятичные числа в диапазоне от положительных 79,228,162,514,264,337,593,543,950,335 до отрицательных 79,228,162,514,264,337,593,543,950,335. Тип десятичного значения подходит для финансовых расчетов, требующих большого количества значащих целых и дробных цифр и без ошибок округления. Тип Decimal не устраняет необходимость округления. Скорее, это минимизирует ошибки из-за округления.
Я хотел бы указать на этот превосходный ответ от zneak о том, почему не следует использовать double.
Ответ 3
Используйте Денежный шаблон от Шаблоны архитектуры корпоративных приложений; укажите сумму как десятичную, а валюту - как перечисление.
Ответ 4
Десятичная. Если вы выберете double, вы перестанете открывать ошибки округления.
Ответ 5
decimal имеет меньший диапазон, но большую точность - поэтому вы не теряете все эти пенни с течением времени!
Полная информация здесь:
Ответ 6
Согласитесь с шаблоном Money: обращение с валютами слишком громоздко, когда вы используете десятичные знаки.
Если вы создадите Currency-класс, вы можете поместить туда всю логику, связанную с деньгами, включая правильный метод ToString(), больший контроль над синтаксическими значениями и лучший контроль над делениями.
Кроме того, с классом Currency нет возможности непреднамеренно смешивать деньги с другими данными.
Ответ 7
Другой вариант (особенно, если вы катите свой собственный класс) - использовать int или int64 и обозначать нижние четыре цифры (или, возможно, даже 2) как "право десятичной точки". Таким образом, "по краям" вам понадобится "* 10000" на пути и некоторые "/10000" на выходе. Это механизм хранения, используемый Microsoft SQL Server, см. http://msdn.microsoft.com/en-au/library/ms179882.aspx
Единственность этого заключается в том, что все ваше суммирование можно выполнить с помощью (быстрой) целочисленной арифметики.
Ответ 8
Создайте свой собственный класс. Это кажется странным, но тип .Net неадекватен для покрытия разных валют.
Ответ 9
В большинстве приложений, с которыми я работал, используйте decimal
для представления денег. Это основано на предположении, что приложение никогда не будет касаться более одной валюты.
Это предположение может быть основано на другом предположении, что приложение никогда не будет использоваться в других странах с разными валютами. Я видел случаи, когда это оказалось ложным.
Теперь это предположение оспаривается по-новому: новые валюты, такие как биткойн, становятся все более распространенными, и они не характерны для какой-либо страны. Это нереально, что приложение, используемое только в одной стране, все равно может поддерживать несколько валют.
Некоторые люди скажут, что создание или даже использование типа только для денег - "золотое покрытие" или добавление дополнительной сложности за пределы известных требований. Я категорически не согласен. Более вездесущая концепция находится в вашем домене, тем важнее приложить разумные усилия, чтобы использовать правильную абстракцию впереди. Если вы хотите увидеть сложность, попробуйте работать в приложении, которое использовало decimal
, и теперь есть дополнительное свойство Currency
рядом с каждым свойством decimal
.
Если вы используете неправильную абстракцию спереди, заменив ее позже, она будет в сто раз больше работы. Это означает потенциальное введение дефектов в существующий код, и лучшая часть состоит в том, что эти дефекты, скорее всего, будут связаны с деньгами, транзакциями с деньгами или просто с деньгами.
И это не так сложно использовать что-то отличное от десятичного. Google "nuget money type", и вы увидите, что многие разработчики создали такие абстракции (включая меня). Это легко. Это проще, чем использование DateTime
вместо сохранения даты в string
.