关于.net:CultureInfo.InvariantCulture是什么意思?

What does CultureInfo.InvariantCulture mean?

我有一系列这样的文字:

1
var foo ="FooBar";

我想声明一个名为bar的第二个字符串,使其等于我的第一个foo的第一个和第四个字符,所以我这样做:

1
var bar = foo[0].ToString() + foo[3].ToString();

这是预期的效果,但Resharper建议我把Culture.InvariantCulture放在括号内,所以这行的结尾是这样的:

1
2
var bar = foo[0].ToString(CultureInfo.InvariantCulture)
        + foo[3].ToString(CultureInfo.InvariantCulture);

这意味着什么,它会影响程序的运行方式吗?


并非所有区域性对日期和十进制/货币值使用相同的格式。

当您将存储为字符串的输入值(read)转换为DateTimefloatdoubledecimal时,这对您很重要。如果您尝试将上述数据类型格式化为字符串(写入)以进行显示或存储,这也很重要。

如果您知道您的日期和小数/货币值将提前处于什么特定的文化中,您可以使用特定的CultureInfo属性(即CultureInfo("en-GB"))。例如,如果需要用户输入。

如果您正在格式化或解析一个字符串,则使用CultureInfo.InvariantCulture属性,该字符串应由一个独立于用户本地设置的软件来解析。

默认值是CultureInfo.InstalledUICulture,因此默认的cultureinfo取决于执行操作系统的设置。这就是为什么你应该始终确保文化信息符合你的意图(参见马丁的回答以获得一个好的指导方针)。

  • CultureInfo.InvariantCulture示例
  • StackOverflow上的CultureInfo.InvariantCulture
  • CultureInfo.InvariantCulture msdn文章
  • 预定义的CultureInfo名称


当数字、日期和时间被格式化为字符串或从字符串中解析时,区域性用于确定如何完成。例如,在主导的en-US文化中,您有以下字符串表示:

  • 1000000.00-一百万,含两位小数
  • 2013年1月29日-发布日期

在我的文化(da-DK中),值具有以下字符串表示:

  • 1000.000.000,00-100万,含两位数分数
  • 2013年1月29日-发布日期

在Windows操作系统中,用户甚至可以自定义数字和日期/时间的格式,也可以选择其他区域性而不是其操作系统的区域性。所使用的格式是用户的选择,这就是它应该是什么样的格式。

因此,当您格式化要向用户显示的值时,例如使用ToStringString.Format,或者使用DateTime.ParseDecimal.Parse从字符串中解析时,默认值是使用CultureInfo.CurrentCulture。这允许用户控制格式。

但是,许多字符串格式和解析实际上不是在应用程序和用户之间交换的字符串,而是在应用程序和某些数据格式(例如XML或CSV文件)之间交换的字符串。在这种情况下,您不想使用CultureInfo.CurrentCulture,因为如果格式化和解析是用不同的区域性完成的,它可能会中断。在这种情况下,您希望使用CultureInfo.InvariantCulture(基于en-US文化)。这样可以确保值可以无问题地往返。

Resharper警告您的原因是,有些应用程序编写者不知道这一区别,这可能会导致意外的结果,但他们从未发现这一点,因为他们的CultureInfo.CurrentCultureen-US,其行为与CultureInfo.InvariantCulture相同。但是,一旦应用程序在另一个区域性中使用,有可能使用一个区域性进行格式化,另一个区域性进行分析,应用程序可能会中断。

综上所述:

  • 如果要格式化或解析用户字符串,请使用CultureInfo.CurrentCulture(默认值)。
  • 如果您正在格式化或解析一个应该由软件来解析的字符串,请使用CultureInfo.InvariantCulture
  • 很少使用特定的国家文化,因为用户无法控制如何进行格式化和解析。


据微软称:

The CultureInfo.InvariantCulture property is neither a neutral nor a
specific culture. It is a third type of culture that is
culture-insensitive. It is associated with the English language but
not with a country or region.

(来自http://msdn.microsoft.com/en-us/library/4c5zdc6a(vs.71.aspx)

所以不变的文化与"我们"的文化相似,但并不完全相同。如果你写:

1
2
3
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"

然后s1和s2将具有相似的格式,但不变文化添加前导零,"en-us"使用AM或PM。

因此,当您将日期保存到文本文件或分析数据时,InvariantCulture更适合内部使用。当您向最终用户提供数据(日期、货币…)时,指定的CultureInfo更好。


对于数字(小数点、逗号等),它们通常在特定的区域性中是首选的。

要做到这一点,一个合适的方法是将其设置为文化级别(对于德语),如下所示:

1
Thread.CurrentThread.CurrentCulture.NumberFormat = new CultureInfo("de").NumberFormat;

JetBrains提供了一个合理的解释,但是如果我在一个我知道只会用英语的网站上工作,我只是忽略了这个建议。