2009-09-28 14 views
13

Me gustaría asegurar que ciertos números en mi aplicación se impriman sin separadores, agrupaciones, etc. sin importar cuál sea el entorno actual. Parece que los dos métodos siguientes producen los mismos resultados (posiblemente hay más):ToString ("0") versus ToString (CultureInfo.InvariantCulture)

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

¿Sabe usted de algún caso de bordes o caprichos? ¿Cuál es más "correcto"? ¿Cuál usarías?

Solía ​​usar el segundo, pero recientemente encontré el primero y comencé a usarlo porque no requiere el using System.Globalization adicional.

Respuesta

0

Si usted está queriendo asegurarse de especificar "sin formato, sin importar lo que" yo personalmente creo que la primera opción que tiene:

123456789.ToString("0"); 

mejor comunica la intención. La desventaja sería si una cultura anula la cadena de formato de "0" para el tipo numérico que está utilizando.

+0

Oh, yo ahora sé que se puede reemplazar las cadenas de formato? Necesito buscarlo. –

+0

¿Estás seguro de la sobrecarga? MSDN (http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx) dice: "Cualquier otro carácter único [que no sea uno de esos estándares] arroja una FormatException en tiempo de ejecución". –

+0

No estaba seguro de si este era el caso o no. Veo que un viaje rápido a la biblioteca de MSDN me lo habría mostrado :). –

2

Según lo veo, el primero en formatear es un número con al menos un carácter que utiliza la cultura predeterminada de la computadora. El segundo lo formateará como un número según las reglas de InvariantCulture.

Bobby

+0

Corrígeme si me equivoco: pensé que no se aplicaron grupos de dígitos, separadores, etc. a 123456789.ToString ("0")? –

+0

Uhhh ... realmente no es así. Lo he confundido con un símbolo de formato como "N0", que sí aplica las reglas de cultura actuales. Tiene razón, dado que el 0 es un formato directo, no se aplica _any_ información cultural. Sin embargo, alguien también podría usar 123456789.ToString(); . – Bobby

5

Los dos métodos no son equivalentes: el primero es el uso de la CurrentCulture. Esto podría generar puntos/comas adicionales en ciertas culturas (no tengo ejemplos).

Cuando utiliza InvariantCulture, está seguro de que siempre se utiliza el mismo formato.

Editar: Y, si usa CodeAnalysis, se quejará cuando no utilice CultureInfo.

+0

Probé el primero modificando la cultura del hilo actual, y no lo afectó. Creo que el "0" significa: al menos un dígito + agrupación sin dígitos o separadores. Si quisiera tener un grupo de dígitos o separadores, creo que tendría que hacer algo como "000,000". –

+2

Pero tiene razón: InvariantCulture "suena" más explícitamente. Incluso MSDN dice "... está asociado con el idioma inglés, pero no con ningún país/región". Hmm, cuando pienso en más, ToString (CultureInfo.InvariantCulture), significa que el número está formateado con la "G". Todo simplemente funciona SOLAMENTE porque "G" no parece estar usando ninguna agrupación. PERO (simplemente lo busqué) la cultura invariante tiene una agrupación especificada. Por ejemplo, pruebe 12345789.ToString ("N", CultureInfo.InvariantCulture). –

17

Basándome en las respuestas y la discusión aquí, investigué un poco más. Aquí es lo que encontré:

  • Cuando se utiliza 12345678.ToString() sin ningún argumento, .NET utiliza en general el especificador de formato general de "G" que se ve afectado solamente por NumberFormatInfo.NegativeSign, NumberFormatInfo. NumberDecimalSeparator, NumberFormatInfo.NumberDecimalDigits y NumberFormatInfo.PositiveSign. Para mí esto dice que en cualquier cultura 12345678.ToString() siempre debe producir "12345678".

  • Si desea dígitos separados, es necesario utilizar el formato numérico especificador "N" (o, por supuesto, para proporcionar una cadena de formato personalizado). La agrupación de dígitos también se aplica a "C" y "P".

  • La cultura invariante no de hecho especifica dígitos agrupación (por 3 dígitos, por supuesto) y un separador de dígitos. Por lo tanto, el motivo por el que 123456789.ToString(CultureInfo.InvariantCulture) produce "123456789" no se debe a la cultura invariable, sino al especificador de formato numérico general predeterminado "G".

, así que diría que la conclusión es que es perfectamente bien que no se preocupe sobre los argumentos adicionales y sólo tiene que utilizar:

12345678.ToString() 

creo que esto lo mejor de todos los casos porque significa que generalmente ni siquiera necesita llamar al ToString() porque la mayoría de las funciones de impresión/escritura aceptan todo tipo de argumentos y hacen el ToString() por usted.

1

2 líneas hacen cosas diferentes. La primera línea formatea el número con la cultura local y la segunda lo convierte en cadena sin formato, pero usando CultureInfo.InvariantCulture.

Utiliza CultureInfo.InvariantCulture con este tipo de métodos (ToString, ToLower ...) para asegurarse de que cuando el valor sea utilizado por cualquier software (base de datos, otra biblioteca ...), sin importar su cultura , dará como resultado el mismo valor y cuando puedan recoger este valor, pueden seguir procesándolo. Sin embargo, si no lo usa, el otro software tiene que descubrir cuál es su cultura. ¿Quisiste decir separador decimal con coma u otra cosa ...?

Todos y todas usan CultureInfo.InvariantCulture cuando desea intercambiar/usar valores entre bibliotecas, bases de datos y usar CultureInfo.CurrentCulture para mostrar a los usuarios de su aplicación.

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

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

(~ 5 años más tarde ...)

que estaba buscando a esta pregunta exacta, pero como no hubo respuesta aceptada y aunque Ene Zich es correcta pensé que iba a armar un poco ejemplo para probar esto.

También llegaría a decir que no hay diferencia entre .ToString(), .ToString ("0") y .ToString (Cualquier información de cultura) (en cuanto a números enteros y decimales)

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

el .ToString() y .ToString (CultureInfo.InvariantCulture) siempre dan el mismo resultado para los enteros.

El código siguiente proporciona "809 cultivos probados, 0 encontraron diferencias" número en mi 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."); 
Cuestiones relacionadas