2011-01-13 13 views
7

domanda breve:C# decimal.Parse comportamento

Perché questi '.....' valido per l'analisi di un decimale nel .NET (C#):

decimal res = decimal.Parse("8......15"); // returns 815 
decimal res = decimal.Parse("8...15");  // returns 815 
decimal res = decimal.Parse("8..15");  // returns 815 

Qual è la ragione per Questo?

+0

ho check-in .NET4.0. Alza un'eccezione di formato – HuBeZa

+0

Che cultura stai usando? Quelle stringhe non possono essere analizzate usando la mia cultura attuale o la cultura invariabile. – LukeH

+0

Penso che sia una pigrizia programmatrice. Non ho visto un luogo che usa mille separatori in modo approssimativo. – HuBeZa

risposta

18

Non funziona per me. Sei per caso in una cultura in cui "." è il separatore delle migliaia e "," è il punto decimale? Decimal.Parse (e chiamate simili) utilizzano la cultura corrente del thread per impostazione predefinita. Se questa è una cosa buona o non è discutibile, ma irrilevante per comportamento effettivo :)

provare a specificare CultureInfo.InvariantCulture nella chiamata decimal.Parse:

decimal res = decimal.Parse("8......15", CultureInfo.InvariantCulture); 

credo che si comporterà come previsto.

+0

Penso che tu abbia centrato la testa. Analizza correttamente se usi la cultura 'de-DE', per esempio. – LukeH

+0

'es-ES' a. Che strana cultura – HuBeZa

+0

Infatti. My CurrentCulture è "nl-BE", NumberDecimalSeparator = "," e NumberGroupSeparator = "." Grazie! Ma è piuttosto strano che permettano tale notazione. – juFo

1

Non so perché, ma so come funziona (codice decimale codice parte vedi sotto). Penso che per l'ultima volta sia sufficiente attivare il flag del punto e saltare tutti i punti.

while (true) 
{ 
    if (((ch >= '0') && (ch <= '9')) || (((options & NumberStyles.AllowHexSpecifier) != NumberStyles.None) && (((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F'))))) 
    { 
     //Here goes some code... 
    } 
    else if ((((options & NumberStyles.AllowDecimalPoint) != NumberStyles.None) && ((num & 0x10) == 0)) 
    && (((chPtr2 = MatchChars(p, currencyDecimalSeparator)) != null) || ((flag && ((num & 0x20) == 0)) 
    && ((chPtr2 = MatchChars(p, numberDecimalSeparator)) != null)))) 
    { 
     num |= 0x10; 
     p = chPtr2 - 1; 
    } 
} 

Utilizzare lo strumento riflettore per indagare su tutto il codice.

+0

Interessante! È bello vedere il codice parte relativo a HexSpecifier. – juFo

2

Immagino che sia perché il parser non si preoccupa veramente dei separatori di gruppo - sono irrilevanti per il processo di conversione di una stringa in un decimale.

Noi li chiamiamo migliaia di separatori, ma in realtà non lo sono. Si tratta di separatori di gruppo: è possibile dividere ogni 3 cifre, ogni 10 cifre, ogni 1 cifra, quindi perché non tutte le 0 cifre?

È interessante notare che il codice è cambiato per .NET 4 - questa è la relativa uscita da riflettore per me:

else 
{ 
    if (((currencySymbol == null) || 
     ((chPtr2 = MatchChars(p, currencySymbol)) == null)) && 
     ((ansiCurrencySymbol == null) || 
     ((chPtr2 = MatchChars(p, ansiCurrencySymbol)) == null))) 
    { 
     break; 
    } 
    num |= 0x20; 
    currencySymbol = null; 
    ansiCurrencySymbol = null; 
    p = chPtr2 - 1; 
}