2009-04-13 8 views
57

Domanda semplice - perché il tipo Decimal definisce queste costanti? Perché preoccuparsi?Qual è lo scopo di Decimal.One, Decimal.Zero, Decimal.MinusOne in .Net

Sto cercando un motivo per cui questo è definito dalla lingua, non da possibili usi o effetti sul compilatore. Perché metterlo lì dentro in primo luogo? Il compilatore può altrettanto facilmente 0m in linea come potrebbe Decimal.Zero, quindi non lo sto comprando come scorciatoia del compilatore.

+0

Non credo che queste risposte spieghino adeguatamente il motivo per cui questi valori sono presenti. Sto ascoltando alcuni effetti e l'utilizzo, ma quello che sto cercando è WHY è stato progettato nel linguaggio, e perché non è lì in Float, per esempio, o Int32 ... – Jasmine

risposta

27

Piccolo chiarimento. In realtà sono valori statici di sola lettura e non costanti. Questo ha una netta differenza in .Net perché i valori costanti sono in linea da parte dei vari compilatori e quindi è impossibile tracciare il loro utilizzo in un assembly compilato. I valori statici di sola lettura tuttavia non vengono copiati ma vengono invece indicati come riferimenti. Questo è vantaggioso per la tua domanda perché significa che il loro utilizzo può essere analizzato.

Se si utilizza Reflector e si scava attraverso il BCL, si noterà che MinusOne e Zero vengono utilizzati solo nel runtime VB. Esiste principalmente per offrire conversioni tra valori decimali e booleani.Perchè MinusOne viene usato per coincidenza in un thread separato oggi (link)

Stranamente, se si guarda il valore Decimal.One si noterà che non viene utilizzato da nessuna parte.

Per quanto riguarda il motivo per cui sono esplicitamente definiti ... Dubito che ci sia un motivo duro e veloce. Lì appare come senza prestazioni specifiche e solo un po 'una misura di comodità che può essere attribuita alla loro esistenza. Il mio indovina è che sono stati aggiunti da qualcuno durante lo sviluppo del BCL per la loro convenienza e non sono mai stati rimossi.

EDIT

Dug la questione const un po 'di più dopo un commento di @Paleta. La definizione C# Decimal.One utilizza il modificatore const tuttavia viene emessa come static readonly a livello IL. Il compilatore C# utilizza un paio di trucchi per rendere questo valore praticamente indistinguibile da un const (letterali inline, ad esempio). Questo apparirebbe in una lingua che riconosce questo trucco (VB.Net riconosce questo, ma F # non lo riconosce).

+0

Non è corretto che questi valori sono in sola lettura, guardando il .NET Framework decimale metada è possibile vedere il seguente [DecimalConstant (0, 0, 4294967295, 4294967295, 4294967295)] \t \t const decimale pubblici MaxValue = 79228162514264337593543950335m; [DecimalConstant (0, 128, 0, 0, 1)] \t \t public const decimal MinusOne = -1m; – Paleta

+0

@Paleta, no sono 'readonly'. Ho verificato ciò osservando i metadati e la pagina MSDN per i valori di hte. http://msdn.microsoft.com/en-us/library/system.decimal.one(VS.80).aspx – JaredPar

+0

Devo non essere d'accordo con te e la tua risposta, guarda il codice mscorlib.dll riflesso qui http: //reflector.webtropy.com/default.aspx/[email protected]/[email protected]/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/[email protected]/1305376/[email protected] quelli dichiarati come costanti, MSDN non è corretto – Paleta

-3

mio opinione su di esso è che sono lì per aiutare evitare numeri magici.

I numeri magici sono praticamente ovunque nel codice in cui si dispone di un numero in sospeso. Per esempio:

int i = 32; 

Questo è problematico, nel senso che nessuno può dire il motivo per cui i è sempre impostato a 32, o che cosa significa 32, o se dovrebbe essere 32 a tutti. È magico e misterioso.

In modo simile, io spesso vedere il codice che fa questo

int i = 0; 
int z = -1; 

perché sono essere impostato a 0 e -1? È solo una coincidenza? Significano qualcosa? Chissà?

Mentre Decimal.One, Decimal.Zero, ecc Non vi dico che cosa i valori medi nel contesto dell'applicazione (forse zero significa "mancante", ecc), si fa che il valore è stato deliberatamente dire, e probabilmente ha un significato.

Pur non essendo perfetto, questo è molto meglio di quanto non dicendo nulla :-)

Nota E 'Non per l'ottimizzazione. Osservare questo codice C#:

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

Se si guarda alla bytecode generato utilizzando ildasm, entrambe le opzioni risultano in identici MSIL. System.Decimal è un tipo di valore, quindi Decimal.Zero non è più "ottimale" di un semplice valore letterale.

+0

Alcune informazioni aggiuntive: http: // gregbeech.com/blogs/tech/archive/2008/07/07/emitting-decimal-pseudo-constants-with-reflection-emit.aspx – boj

+1

Ma non c'è la proprietà Int32.Zero ... – Guffa

+0

Il tuo argomento mi fa male la testa. Sono numeri, diventano numeri magici solo quando inizi ad attribuire loro un significato casuale come -1 significa fare i piatti e 1 significa cuocere torte. Decimale.Uno è altrettanto magico di 1 ma probabilmente più difficile da leggere (ma forse più ottimale). –

20

Alcuni linguaggi .NET non supportano decimale come tipo di dati ed è più conveniente (e più veloce) in questi casi scrivere Decimal.ONE anziché nuovo Decimal (1).

La classe BigInteger di Java ha ZERO e UNO, per lo stesso motivo.

+1

Qualcuno può spiegarmi questo? 6 voti positivi significa che deve essere una buona risposta - ma: Come fa un linguaggio .Net che non supporta i decimali come un tipo di dati beneficiano di una proprietà condivisa di sola lettura che restituisce un decimale ed è definito come parte di la classe decimale? –

+7

Probabilmente intendeva dire che se una lingua non ha valori letterali decimali, l'uso di una costante sarebbe più efficiente della conversione di un letterale int in un decimale. Ogni linguaggio .NET supporta il tipo di dati System.Decimal, fa parte del CLR. – Niki

+1

sì Niki è quello che volevo dire. Ovviamente puoi usare System.Decimal in tutti i linguaggi .NET, ma alcuni lo supportano meglio (come C# che ha una parola chiave decimale e letterali decimali) e altri ancora. Spiacente, l'inglese non è la mia lingua madre ... – mihi

-4

Questi 3 valori arghhh !!!

penso che possono avere qualcosa a che fare con quello che io chiamo finale 1 di

dire che hai questa formula:

(x) 1,116,666 mila + (y) = (z) 2.00000

ma x, z sono arrotondati per 0,11 e 2,00 e viene chiesto di calcolare (y).

quindi si può pensare y = 2.00 - 1.11. In realtà e equivale a 0.88 ma riceverai 0.89. (c'è un 0.01 in differenza).

dipende dal valore reale delle xey i risultati varia da -0.01 a 0,01, e in alcuni casi quando si tratta di un gruppo di quelle finali 1 di, e per facilate le cose, si può controllare se il valore finale è uguale a Decimal.MinusOne/100, Decimal.One/100 o Decimal.Zero/100 per risolverli.

questo è il modo in cui ho fatto uso di loro.

+5

Di cosa stai parlando? Stai facendo una cattiva matematica con valori inesatti e poi usi l'operatore di divisione per inventare il tuo epsilon? Cosa ti fa pensare che il risultato sarà sempre spento esattamente di 0,01 e non (per esempio) di 0,005? Se questi valori rappresentano denaro, sarei spaventato di fare affari con la tua applicazione. –

+0

:) Non sto calcolando un risultato finale, devo dare il valore di (y) per il formato arrotondato. come lo farai? – Hassen