2009-09-28 16 views
13

Mi piacerebbe assicurarmi che determinati numeri nella mia applicazione vengano stampati senza separatori, raggruppamenti ecc. A prescindere dall'ambiente corrente. Sembra che i seguenti due metodi producono gli stessi risultati (ci sono forse più):ToString ("0") versus ToString (CultureInfo.InvariantCulture)

123456789.ToString("0"); 
123456789.ToString(CultureInfo.InvariantCulture); 

sono a conoscenza di casi limite o capricci? Qual è più "corretto"? Quale useresti?

Ero solito utilizzare il secondo, ma recentemente ho trovato il primo e ho iniziato ad usarlo perché non richiede l'ulteriore using System.Globalization.

risposta

0

Se hai intenzione di fare in modo di specificare "senza formattazione, non importa quale" Personalmente penso che la prima opzione si ha:

123456789.ToString("0"); 

meglio comunica l'intento. Lo svantaggio sarebbe se una cultura superava la stringa di formato di "0" per il tipo numerico che stai utilizzando.

+0

Oh, ho ora so che è possibile ignorare le stringhe di formato? Devo cercarlo. –

+0

Sei sicuro del sovraccarico? MSDN (http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx) dice: "Qualsiasi altro singolo carattere [rispetto a uno di quelli standard] genera un FormatException in fase di esecuzione." –

+0

Non ero sicuro se questo fosse il caso o no. Vedo che un rapido viaggio nella libreria MSDN mi avrebbe mostrato :). –

2

Come ho visto, il primo si formatterà è un numero con almeno un carattere che utilizza la cultura predefinita del computer. Il secondo lo formatterà come un numero in base alle regole di InvariantCulture.

Bobby

+0

Correggetemi se ho torto: ho pensato che nessun gruppo numerico, separatore, ecc. Si applica a 123456789.ToString ("0")? –

+0

Uhhh ... davvero no. L'ho scambiato per un simbolo di formattazione come "N0", che applica le regole di cultura correnti. Hai ragione, dal momento che lo 0 è una formattazione diretta non si applica _any_ informazioni sulla cultura. Tuttavia, qualcuno potrebbe utilizzare anche 123456789.ToString(); . – Bobby

5

I due metodi non sono equivalenti: il primo è utilizzare l'CurrentCulture. Questo potrebbe portare a punti/virgole in alcune culture (non ho esempi).

Quando si utilizza InvariantCulture, si è certi che viene sempre utilizzata la stessa formattazione.

Modifica: E, se si utilizza CodeAnalysis, si lamenterà quando non si utilizza CultureInfo.

+0

Ho provato il primo modificando la cultura del thread corrente e non ha avuto alcun effetto. Penso che lo "0" significhi: almeno una cifra + nessun raggruppamento o separatore di cifre. Se volessi avere qualche gruppo di cifre o separatori, penso che dovrei fare qualcosa come "000.000". –

+2

Ma hai ragione: InvariantCulture "suona" in modo più esplicito. Anche MSDN dice "... è associato alla lingua inglese ma non a nessun paese/regione". Hmm, quando penso a più, ToString (CultureInfo.InvariantCulture), significa che il numero se formattato usando la "G". Succede tutto solo di lavorare SOLO perché "G" sembra non utilizzare alcun raggruppamento. MA (l'ho appena visto) la cultura invariante ha specificato alcuni gruppi. Ad esempio, prova 12345789.ToString ("N", CultureInfo.InvariantCulture). –

17

Sulla base delle risposte e della discussione qui, ho fatto qualche altra indagine. Ecco cosa ho trovato:

  • Quando si utilizza 12345678.ToString() senza argomenti, .NET utilizza il generale formato generale identificatore "G" che è influenzato solo da NumberFormatInfo.NegativeSign, NumberFormatInfo. NumberDecimalSeparator, NumberFormatInfo.NumberDecimalDigits e NumberFormatInfo.PositiveSign. Per me questo dice che in ogni cultura 12345678.ToString() dovrebbe sempre produrre "12345678".

  • Se si vuole cifre separati, è necessario utilizzare il formato numerico specificatore "N" (o, naturalmente, per fornire una stringa di formato personalizzato). Il raggruppamento delle cifre si applica anche a "C" e "P".

  • Il cultura invarianti non effettivamente specifica cifre raggruppamento (da 3 cifre, naturalmente) e un separatore cifre. Quindi la ragione per cui 123456789.ToString(CultureInfo.InvariantCulture) produce "123456789" non è a causa della cultura invariante, ma è a causa dell'identificatore di formato numerico generale predefinito "G".

quindi direi che la conclusione è che è perfettamente OK non preoccuparsi di eventuali argomenti extra e basta usare:

12345678.ToString() 

Penso che questo il meglio da tutti i casi perché significa che di solito non è necessario chiamare anche ToString() perché la maggior parte delle funzioni di stampa/scrittura accetta tutti i tipi di argomenti e fa il ToString() per te.

1

2 linee fanno cose diverse. La prima riga formatta il numero con la cultura locale e la seconda la converte in stringa senza formattazione, ma utilizzando CultureInfo.InvariantCulture.

Si utilizza CultureInfo.InvariantCulture con questo tipo di metodi (ToString, ToLower ...) per assicurarsi che quando il valore viene utilizzato da qualsiasi software (database, un'altra libreria ...), indipendentemente dalla loro cultura , risulterà lo stesso valore e quando possono raccogliere questo valore, possono continuare a elaborarlo. Tuttavia, se non lo usi, l'altro software deve capire qual è la tua cultura. Intendevi separatore decimale con virgola o qualcos'altro ...?

Tutti e tutti utilizzano CultureInfo.InvariantCulture quando si desidera scambiare/utilizzare valori tra librerie, database e utilizzare CultureInfo.CurrentCulture per mostrare agli utenti dell'applicazione.

// for softwares 
string mystring1 = 1234.ToString("0", CultureInfo.InvariantCulture); 

// for your application users 
string mystring2 = 1234.ToString("0", CultureInfo.CurrentCulture); 
1

(~ 5 anni dopo ...)

che cercavo questa domanda esatta, ma dal momento che non vi era alcuna risposta accettata e anche se Jan Zich è corretto ho pensato di mettere insieme un po ' esempio per testare questo.

Vorrei anche andare così lontano a dire che non v'è alcuna differenza tra .ToString(), .ToString ("0"), e .ToString (qualsiasi info Cultura) (per quanto interi e decimali sono interessati)

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures) 
    .Except(CultureInfo.GetCultures(CultureTypes.SpecificCultures)); 

foreach(var c in cultures){ 
    var num = (int.MinValue);/* 
    var num = (int.MaxValue);/* 
    var num = (decimal.MinValue);/* 
    var num = (decimal.MaxValue);/* 
--*/ 

    var s1 = num.ToString("0") ; 
    var s2 = num.ToString(c); 
    if(s1 != s2){ 
     var s = string.Format("{2}: {0} {1}",s1,s2,c); 
     s.Dump(); 
    } 
} 

LinqPad snippet

0

il .ToString() e .ToString (CultureInfo.InvariantCulture) danno sempre lo stesso risultato per gli interi.

Il codice qui sotto dà "809 culture testate, 0 differenze riscontrate" risultato sul mio PC:

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures).ToArray(); 
var numbers = new[] { 0, -1, 1, int.MinValue, int.MaxValue }; 

var diffsFound = 0; 
foreach (var culture in cultures) 
{ 
    foreach (var number in numbers) 
    { 
     var s1 = number.ToString(); 
     var s2 = number.ToString(culture); 
     if (s1 != s2) 
     { 
      Console.WriteLine($"{culture.DisplayName}: {s1} != {s2}"); 
      diffsFound++; 
     } 
    } 
} 

Console.WriteLine($"{cultures.Length} cultures tested, {diffsFound} differences found.");