Quel est le meilleur type de données à utiliser pour de l'argent en C #?
Comme il est décrit à décimal par:
Le mot clé décimal indique un type de données 128 bits. Par rapport aux types à virgule flottante, le type décimal a plus de précision et une plage plus petite, ce qui le rend approprié pour les calculs financiers et monétaires .
Vous pouvez utiliser un nombre décimal comme suit:
decimal myMoney = 300.5m;
Le type de valeur décimale représente des nombres décimaux compris entre 79 228,162,144,264,337,593,543,935,335 positif et négatif 79,228,162,514,264,337,593,543,950,335. Le type de valeur décimale convient aux calculs financiers nécessitant un grand nombre de chiffres entiers et fractionnaires significatifs et aucune erreur d'arrondi. Le type décimal n'élimine pas le besoin d'arrondir. Cela minimise plutôt les erreurs dues à l'arrondissement.
Je voudrais pointer vers cette excellente réponse par zneak sur pourquoi double ne devrait pas être utilisé.
Utilisez le motif Money de Patterns of Enterprise Application Architecture ; spécifiez le montant en décimal et la devise en enum.
Décimal. Si vous choisissez double, vous vous exposez à des erreurs d'arrondi.
decimal a une plage plus petite, mais une plus grande précision - pour ne pas perdre toutes ces sous au fil du temps!
Détails complets ici:
D'accord avec le modèle Money: la gestion des devises est tout simplement trop lourde lorsque vous utilisez des décimales.
Si vous créez une classe Currency, vous pouvez alors y placer toute la logique relative à la monnaie, y compris une méthode correcte ToString (), un meilleur contrôle des valeurs d’analyse et un meilleur contrôle des divisions.
En outre, avec une classe Currency, il n'y a aucune chance de mélanger involontairement de l'argent avec d'autres données.
Une autre option (surtout si vous utilisez votre propre classe) consiste à utiliser un int ou un int64 et à désigner les quatre chiffres inférieurs (ou même 2) comme "à droite du point décimal". Donc, "sur les bords", vous aurez besoin de "* 10000" pour entrer et de "/ 10000" pour sortir. Il s’agit du mécanisme de stockage utilisé par Microsoft SQL Server, voir http://msdn.Microsoft.com/en-au/library/ms179882.aspx
La noblesse de ceci est que toute votre somme peut être faite en arithmétique (rapide) d’entiers.
La plupart des applications avec lesquelles j'ai travaillé utilisent decimal
pour représenter de l'argent. Ceci est basé sur l'hypothèse que l'application ne sera jamais concernée par plus d'une devise.
Cette hypothèse peut reposer sur une autre hypothèse, à savoir que l'application ne sera jamais utilisée dans d'autres pays avec des devises différentes. J'ai vu des cas où cela s'est avéré faux.
Maintenant, cette hypothèse est remise en question d'une nouvelle manière: de nouvelles monnaies telles que le Bitcoin sont de plus en plus courantes et elles ne sont spécifiques à aucun pays. Il n'est pas irréaliste qu'une application utilisée dans un seul pays doive toujours prendre en charge plusieurs devises.
Certaines personnes diront que créer ou même utiliser un type juste pour de l'argent est un "placage d'or" ou une complexité supplémentaire au-delà des exigences connues. Je suis fortement en désaccord. Plus un concept est omniprésent dans votre domaine, plus il est important de faire un effort raisonnable pour utiliser la bonne abstraction dès le départ. Si vous voulez voir la complexité, essayez de travailler dans une application qui utilisait auparavant decimal
et il existe maintenant une propriété supplémentaire Currency
à côté de chaque propriété decimal
.
Si vous utilisez la mauvaise abstraction en amont, la remplacer plus tard représentera cent fois plus de travail. Cela signifie qu’il est possible d’introduire des défauts dans le code existant, et le mieux, c’est que ces défauts impliqueront vraisemblablement des sommes en argent, des transactions avec de l’argent ou tout simplement de l’argent.
Et ce n'est pas si difficile d'utiliser autre chose que décimale. Google "Nuget Money Type" et vous verrez que de nombreux développeurs ont créé de telles abstractions (y compris moi.) C'est facile. C'est aussi simple que d'utiliser DateTime
au lieu de stocker une date dans un string
.
Créez votre propre classe. Cela semble étrange, mais un type .Net est insuffisant pour couvrir différentes devises.