.net - studio - ¿Qué significa CultureInfo.InvariantCulture?
resharper visual studio code (5)
Tengo una cadena de texto como esta:
var foo = "FooBar";
Quiero declarar una segunda cadena llamada bar
y hacer que este sea igual al primer y cuarto personaje de mi primer foo
, así que lo hago así:
var bar = foo[0].ToString() + foo[3].ToString();
Esto funciona como se esperaba, pero ReSharper me está aconsejando que coloque Culture.InvariantCulture
dentro de mis corchetes, por lo que esta línea termina así:
var bar = foo[0].ToString(CultureInfo.InvariantCulture)
+ foo[3].ToString(CultureInfo.InvariantCulture);
¿Qué significa esto y afectará cómo se ejecuta mi programa?
Cuando los números, fechas y horas se formatean en cadenas o se analizan a partir de cadenas, se utiliza una cultura para determinar cómo se hace. Por ejemplo, en la cultura dominante en-US
Tienes estas representaciones de cadenas:
- 1,000,000.00 - un millón con una fracción de dos dígitos
- 29/01/2013 - fecha de esta publicación
En mi cultura ( da-DK
) los valores tienen esta representación de cadena:
- 1.000.000,00 - un millón con una fracción de dos dígitos
- 29-01-2013 - fecha de esta publicación
En el sistema operativo Windows, el usuario incluso puede personalizar cómo se formatean los números y la fecha / horas, y también puede elegir otra cultura que no sea la cultura de su sistema operativo. El formato utilizado es la elección del usuario, que es como debería ser.
Por lo tanto, cuando formatee un valor que se mostrará al usuario utilizando, por ejemplo, ToString
o String.Format
o se analizará desde una cadena utilizando DateTime.Parse
o Decimal.Parse
el valor predeterminado es usar CultureInfo.CurrentCulture
. Esto le permite al usuario controlar el formateo.
Sin embargo, una gran cantidad de cadenas de formato y análisis no son realmente cadenas intercambiadas entre la aplicación y el usuario, sino entre la aplicación y algunos formatos de datos (por ejemplo, un archivo XML o CSV). En ese caso, no desea utilizar CultureInfo.CurrentCulture
porque si el formateo y el análisis se realizan con diferentes culturas, puede romperse. En ese caso, quiere usar CultureInfo.InvariantCulture
(que se basa en la cultura en-US
). Esto asegura que los valores pueden ida y vuelta sin problemas.
La razón por la que ReSharper le advierte es porque algunos escritores de aplicaciones desconocen esta distinción que puede conducir a resultados no deseados, pero nunca lo descubren porque su CultureInfo.CurrentCulture
es en-US
y tiene el mismo comportamiento que CultureInfo.InvariantCulture
. Sin embargo, tan pronto como la aplicación se utiliza en otra cultura donde existe la posibilidad de utilizar una cultura para formatear y otra para analizar, la aplicación puede fallar.
Entonces, para resumir:
- Use
CultureInfo.CurrentCulture
(valor predeterminado) si está formateando o analizando una cadena de usuario. - Utilice
CultureInfo.InvariantCulture
si está formateando o analizando una cadena que debe ser parseable por un software. - Rara vez se utiliza una cultura nacional específica porque el usuario no puede controlar cómo se realiza el formateo y el análisis sintáctico.
De acuerdo con Microsoft:
La propiedad CultureInfo.InvariantCulture no es una cultura neutral ni específica. Es un tercer tipo de cultura que es insensible a la cultura. Está asociado con el idioma inglés, pero no con un país o región.
(desde http://msdn.microsoft.com/en-us/library/4c5zdc6a(vs.71).aspx )
Así que InvariantCulture es similar a la cultura "en-US" pero no exactamente lo mismo. Si tú escribes:
var d = DateTime.Now;
var s1 = d.ToString(CultureInfo.InvariantCulture); // "05/21/2014 22:09:28"
var s2 = d.ToString(new CultureInfo("en-US")); // "5/21/2014 10:09:28 PM"
entonces s1 y s2 tendrán un formato similar pero InvariantCulture agrega ceros a la izquierda y "en-US" usa AM o PM.
Así que InvariantCulture es mejor para el uso interno, cuando, por ejemplo, guarda una fecha en un archivo de texto o analiza datos. Y un CultureInfo especificado es mejor cuando presenta datos (fecha, moneda ...) al usuario final.
JetBrains ofrece una explanation razonable, pero si estoy trabajando en un sitio que sé que estará en inglés solamente, simplemente ignoro la sugerencia.
No todas las culturas usan el mismo formato para las fechas y los valores decimales / moneda.
Esto le importará cuando esté convirtiendo valores de entrada (lectura) almacenados como cadenas en DateTime
, float
, double
o decimal
. También importará si intenta formatear los tipos de datos antes mencionados en cadenas (escritura) para su visualización o almacenamiento.
Si conoce la cultura específica en la que sus fechas y valores decimales / moneda estarán disponibles con anticipación, puede usar esa propiedad CultureInfo
específica (es decir, CultureInfo("en-GB")
). Por ejemplo, si espera una entrada de usuario.
La propiedad CultureInfo.InvariantCulture
se utiliza si está formateando o analizando una cadena que debe ser parseable por un software independiente de la configuración local del usuario.
El valor predeterminado es CultureInfo.InstalledUICulture
por lo que CultureInfo predeterminado depende de la configuración del sistema operativo que se está ejecutando. Esta es la razón por la que siempre debes asegurarte de que la información de la cultura se ajuste a tu intención (ver la respuesta de Martin para una buena guía).
Para cosas como números (decimales, comas en cantidades), generalmente se prefieren en la cultura específica.
Una forma adecuada de hacerlo sería establecerlo en el nivel cultural (para el alemán) de esta manera:
Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;