CultureInfo.CurrentUICulture有什么不妥之处?
我刚在我的代码库中启用代码分析规则CA1305,结果出现大量如下警告:
CA1305:The behavior of 'string.Format(string, object)' could vary based on the current user's locale settings. Replace this call in 'some-function' with a call to 'string.Format(IFormatProvider, string, params object[])'
没问题,这也是我启用CA1305的原因。
然而,在某次我遇到类似这样的结构时:
text.SomeParsingMethodWithFormatProvider(CultureInfo.CurrentUICulture)
我收到了以下警告:
Warning CA1305: 'some-function' passes 'CultureInfo.CurrentUICulture' as the 'IFormatProvider' parameter to 'SomeParsingMethodWithFormatProvider'. This property returns a culture that is inappropriate for formatting methods
嗯?那么,CultureInfo.CurrentUICulture 在格式化方法中到底以何种方式不合适?
我无法在文档中找到解释,文档在这里:https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305
解决方案
关于 CA1305 的[较早文档](https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2015/code-quality/ca1305-specify-iformatprovider?view=vs-2015&redirectedfrom=MSDN)对 CultureInfo.CurrentUICulture 的说明更明确一些,因为在指南或规则描述之后,有一段关于其用途的注解,在格式化的上下文中并不相关。
为了确保代码在你的场景中按预期工作,请按照以下准则提供区域性信息:
- 如果该值将显示给用户,请使用当前文化。见
System.Globalization.CultureInfo.CurrentCulture。- 如果该值将由软件存储并访问(持久化到文件或数据库),请使用不变文化。见
System.Globalization.CultureInfo.InvariantCulture。- 如果你不知道该值的去向,请让数据的使用者或提供者指定文化。
请注意,
System.Globalization.CultureInfo.CurrentUICulture的用途 仅用于通过使用System.Resources.ResourceManager类的实例来检索本地化资源。
来自在启用你所看到的警告的提交中添加的注释:[the comments] 以及 [the commit],见下列内容所示:
// Sample message
// This property returns a culture that is inappropriate for formatting methods.
// If the result of 'TestClass.CalleeMethod(string, IFormatProvider)' will be displayed to the user,
// specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter.
// Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk
// or to a database, specify 'CultureInfo.InvariantCulture'.
我们可能会推断,他们决定将这些指南强制应用于已知的 CultureInfo.CurrentUICulture 情况,作为 CA1305 范围的一部分,因为即使提供了一个 IFormatProvider,它始终会是“错误的那个”。
我的理解是,CultureInfo.CurrentUICulture 仅用于由 ResourceManager 使用,专门用于它的 CultureInfo.Name 属性。它还通过成为一个 CultureInfo 实例来实现 IFormatProvider,这只是偶然,因此在实际情况下不应被视为一个有效的 IFormatProvider。