CultureInfo.InvariantCulture是什么意思?


175

我有一串这样的文字:

var foo = "FooBar";

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

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

这可以按预期工作,但是ReSharper建议我将其放在Culture.InvariantCulture括号内,因此此行的结尾如下:

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

这是什么意思,它将影响我的程序的运行方式吗?



37
对于那些寻求5秒答案的人:CultureInfo.InvariantCulture的意思是“我不在乎,我不想首先涉及文化。现在让我使用愚蠢的东西。”
安德鲁

4
@Andrew可以重写MS的所有文档吗?
Yatrix

2
@Yatrix是的,确定。我喜欢!谁付款?
安德鲁

Answers:


153

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

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

如果您知道日期和十进制/货币值将采用哪种特定区域性,则可以使用该特定CultureInfo属性(即CultureInfo("en-GB"))。例如,如果您期望用户输入。

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

默认值为,CultureInfo.InstalledUICulture因此默认的CultureInfo取决于正在执行的操作系统的设置。这就是为什么您应始终确保文化信息符合您的意图的原因(请参阅Martin的回答以获取良好指南)。


3
但是,“ en-US”实际上取决于您的系统设置。
Tracker1 2012年

43
默认值为en-US。这是当地的文化。InvariantCulture当需要独立于本地系统的中性文化格式时,可以使用。例如,使用基于文本的文件格式时。
CodesInChaos

22
要在@CodesInChaos中添加注释:声称默认值为CultureInfo(“ en-US”)完全是错误的。另外,当您不确定提前确定日期和十进制/货币值将采用哪种文化格式时,将使用CultureInfo.InvariantCulture属性语句。使用当前的,不变的或特定的文化是应该明智的决定,如果您弄错了,则可以疏远您的(非美国)用户。如果您不确定,则不应使用不变文化。您需要提前确定。
Martin Liversage 2013年

3
-1由于其他评论中提到的问题。Martin的答案很有帮助,因为它会告诉您何时使用和不使用每种文化。
Ed Greaves 2014年

“如果您只使用美国英语,则不必担心。”:错误,您可能只使用美国英语,但是该软件可以在“ en-GB”或“ de -DE”服务器,那么它将有所作为,另外它还可以吸收客户端的文化(如果您在web.config文件中这样说),而且也可能不是“ en-US” ...
Stefan Steiger

151

将数字,日期和时间格式化为字符串或从字符串中解析时,会使用一种区域性来确定其处理方式。例如,在主流en-US文化中,您具有以下字符串表示形式:

  • 1,000,000.00-一百万,两位小数
  • 1/29/2013-发布日期

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

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

在Windows操作系统中,用户甚至可以自定义数字和日期/时间的格式,还可以选择操作系统以外的其他区域。所使用的格式是用户的选择方式,应该是这样。

所以,当你格式化值使用被显示给用户,例如ToStringString.Format或使用从字符串解析DateTime.ParseDecimal.Parse默认是使用CultureInfo.CurrentCulture。这允许用户控制格式。

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

该ReSharper的给你警告的原因是,一些应用程序编写者不知道这种区别可能导致意想不到的结果,但他们从来没有发现这一点,因为他们CultureInfo.CurrentCulture就是en-US具有相同行为CultureInfo.InvariantCulture。但是,一旦在另一种区域性中使用了该应用程序,就有机会使用一种区域性进行格式化而另一种区域性用于解析该应用程序。

总结一下:

  • CultureInfo.CurrentCulture如果要格式化或解析用户字符串,请使用(默认)。
  • 使用CultureInfo.InvariantCulture如果格式化或解析应该由一个软件是解析的字符串。
  • 由于用户无法控制格式化和解析的方式,因此很少使用特定的国家文化。

1
关于最后一点,“很少使用特定的民族文化...”,货币格式是否会例外?例如,如果我有一个Decimal包含以美元为单位的特定值的变量,我是否想en-US在显示该变量时例外并用作区域性,以确保得到的结果看起来不像是欧元数字?我尝试过 CultureInfo.InvariantCulture,但是将其用于货币标记¤,所以我不确定这是正确的方法。
杰夫B

1
@JeffBridgman:我的建议仅是一般性建议,可能不适用于您的特定情况。但是,我认为您显示小数点(逗号或点)的方式应由用户控制(例如使用CultureInfo.CurrentCulture)。如果除了显示数字还需要货币,那么也许您应该以一致的方式进行操作,即不使用a CultureInfo而是使用像这样的三字母货币代码USD 1,234.56。这样一来,您就不必再考虑将货币映射到文化的问题了。
Martin Liversage

26

根据微软的说法:

CultureInfo.InvariantCulture属性既不是中立的也不是特定的文化。这是对文化不敏感的第三种文化。它与英语相关,但与国家或地区无关。

(摘自http://msdn.microsoft.com/zh-cn/library/4c5zdc6a(vs.71).aspx

因此InvariantCulture与“ en-US”文化相似,但并不完全相同。如果您写:

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将具有类似格式,但InvariantCulture会添加前导零,“ en-US”使用AM或PM。

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


3
我运行了您的示例代码以确认:InvariantCulture使用American MM / dd / yyyy,而不是遵循ISO 8601年度优先格式。尽管如此,它还是用于便携式存储和机械处理,而不是供人类消费。令人困惑
Max Barraclough

4

对于数字(小数点,金额中的逗号)之类的东西,通常在特定区域性中更喜欢它们。

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

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

3

JetBrains提供了合理的解释

“从数据结构到文本的临时转换在很大程度上取决于当前的文化,当在区域设置与原始开发人员的区域设置不同的计算机上执行代码时,可能会导致意想不到的结果。为避免歧义,ReSharper警告您:代码中可能发生此类问题的任何实例。”

但是,如果我在一个网站上工作,那么我只会说英文,那我就忽略了这个建议。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.