Qual è il miglior tipo di dati da utilizzare per denaro in C #?
using System.ComponentModel.DataAnnotations;
... [DataType(DataType.Currency)]
msdn.microsoft.com/en-us/library/...
Qual è il miglior tipo di dati da utilizzare per denaro in C #?
using System.ComponentModel.DataAnnotations;
... [DataType(DataType.Currency)]
msdn.microsoft.com/en-us/library/...
Risposte:
Come è descritto in decimale come:
La parola chiave decimale indica un tipo di dati a 128 bit. Rispetto ai tipi a virgola mobile, il tipo decimale ha più precisione e un intervallo più piccolo, il che lo rende appropriato per i calcoli finanziari e monetari .
È possibile utilizzare un decimale come segue:
decimal myMoney = 300.5m;
Il tipo di valore decimale rappresenta numeri decimali che vanno da 79.228.162.514.264.337.593.543.950.335 positivi a 79.228.162.514.264.337.593.543.950.335 negativi. Il tipo di valore decimale è appropriato per i calcoli finanziari che richiedono un numero elevato di cifre integrali e frazionarie significative e nessun errore di arrotondamento. Il tipo decimale non elimina la necessità di arrotondamento. Piuttosto, minimizza gli errori dovuti all'arrotondamento.
Vorrei sottolineare questa eccellente risposta di zneak sul perché il doppio non dovrebbe essere usato.
Utilizzare il modello Money da Patterns of Enterprise Application Architecture ; specifica l'importo come decimale e la valuta come enum.
Money
nuget ha un link github morto per il sito del progetto, quindi ... nessun documento?
Decimale. Se scegli il doppio ti stai lasciando aperto agli errori di arrotondamento
double
può introdurre errori di arrotondamento perché il virgola mobile non può rappresentare esattamente tutti i numeri (es. 0.01 non ha una rappresentazione esatta in virgola mobile). Decimal
, D'altra parte, non rappresentare i numeri esattamente . (Il trade-off Decimal
ha un intervallo inferiore rispetto al virgola mobile) Il virgola mobile può causare errori di arrotondamento * involontari * (ad esempio 0.01+0.01 != 0.02
). Decimal
può darti errori di arrotondamento, ma solo quando lo hai richiesto (ad es. Math.Round(0.01+0.02)
restituisce zero)
double
e applica con attenzione il ridimensionamento e l'arrotondamento specifico del dominio, se del caso, può essere perfettamente preciso. Se uno è sciatto nel proprio arrotondamento, decimal
può produrre risultati semanticamente errati (ad esempio se si sommano più valori che dovrebbero essere arrotondati al penny più vicino, ma in realtà non li circonda prima). L'unica cosa positiva decimal
è che il ridimensionamento è integrato.
il decimale ha un intervallo più piccolo, ma una maggiore precisione, quindi non perdi tutti quei centesimi nel tempo!
Tutti i dettagli qui:
Concordi con il modello monetario: la gestione delle valute è troppo ingombrante quando si utilizzano i decimali.
Se crei una classe di valuta, puoi quindi inserire tutta la logica relativa al denaro, incluso un metodo ToString () corretto, un maggiore controllo dei valori di analisi e un migliore controllo delle divisioni.
Inoltre, con una classe Currency, non vi è alcuna possibilità di mescolare involontariamente denaro con altri dati.
Un'altra opzione (specialmente se stai lanciando la tua classe) è usare un int o un int64 e designare le quattro cifre inferiori (o forse anche 2) come "diritto del punto decimale". Quindi "ai bordi" avrai bisogno di "* 10000" mentre entri e di "/ 10000" all'uscita. Questo è il meccanismo di archiviazione utilizzato da SQL Server di Microsoft, vedi http://msdn.microsoft.com/en-au/library/ms179882.aspx
La cosa bella è che tutta la tua somma può essere fatta usando l'aritmetica intera (veloce).
Molte applicazioni con cui ho lavorato decimal
rappresentano denaro. Ciò si basa sul presupposto che l'applicazione non riguarderà mai più di una valuta.
Questa ipotesi può essere basata su un'altra ipotesi, secondo cui l'applicazione non verrà mai utilizzata in altri paesi con valute diverse. Ho visto casi in cui ciò si è rivelato falso.
Ora questa ipotesi viene sfidata in un modo nuovo: le nuove valute come Bitcoin stanno diventando più comuni e non sono specifiche per nessun paese. Non è irrealistico che un'applicazione utilizzata in un solo paese possa ancora aver bisogno di supportare valute multiple.
Alcune persone diranno che la creazione o persino l'uso di un tipo solo per soldi è "doratura" o l'aggiunta di ulteriore complessità oltre i requisiti noti. Sono fortemente in disaccordo. Più un concetto ubiquitario è all'interno del tuo dominio, più è importante fare uno sforzo ragionevole per utilizzare l'astrazione corretta in anticipo. Se vuoi vedere la complessità, prova a lavorare in un'applicazione che usava decimal
e ora c'è una Currency
proprietà aggiuntiva accanto a ogni decimal
proprietà.
Se usi l'astrazione sbagliata in anticipo, sostituirla in seguito sarà cento volte più impegnativa. Ciò significa che è possibile che vengano introdotti difetti nel codice esistente e la parte migliore è che tali difetti implicheranno probabilmente somme di denaro, transazioni con denaro o qualsiasi altra cosa con denaro.
E non è così difficile usare qualcosa di diverso dal decimale. Google "nuget money type" e vedrai che numerosi sviluppatori hanno creato tali astrazioni (incluso me.) È facile. È facile come usare DateTime
invece di memorizzare una data in a string
.
Crea la tua classe. Sembra strano, ma un tipo .Net non è adeguato per coprire valute diverse.