我应该总是指定要使用哪个IFormatProvider吗?

5

我尝试在我们产品的几个程序集上运行FxCop,但我得到了很多“Specify IFormatProvider”规则的匹配项。

事实上,其中一些是合法的,但它也匹配这样的代码:

Logger.DebugFormat("Appending file {0}", fileName);

这可以写成

Logger.DebugFormat(CultureInfo.InvariantCulture, "Appending file {0}", fileName);

第二个变量的可读性要差得多。
那么,是否真的建议始终指定IFormatProvider,还是仅仅是规则中使用启发式算法的限制?
3个回答

6

这只适用于具有IFormatProvider重载的方法。

为了解决这个问题,我有两个静态类:InvariantTextCulturedText,分别处理不变文化和当前文化中的字符串。例如,每个类中都有一个格式化方法。这样,我可以进行与文化无关和与文化相关的格式化,而不必每次都指定IFormatProvider

例如:

InvariantText.Format("0x{0:X8}",value);

CulturedText.Format("Appending file {0}",file);

InvariantText.FormatCulturedText.Format只是String.Format方法的包装器,因此同样返回字符串。


您甚至可以使用此模式来包装其他需要区域设置中立和特定区域设置字符串的函数。例如,创建两个方法InvariantLogCulturedLog,它们在您的问题中包装对Logger.DebugFormat的调用,并在每种情况下采用适当的IFormatProvider


1
谢谢,这确实是一个明显的改进,但是对于我的记录器来说它不起作用,因为接口不在我的控制之下...而那些调用正是我最烦恼的 :) 我将把这标记为正确答案,因为到目前为止这真的是最有用的一个。 - Simon Lindgren
InvariantText.Format和CulturedText.Format方法返回字符串。在您的示例中,您可以将记录器方法重写为Logger.DebugFormat(CulturedText.Format("Appending file {0}", fileName)); - Peter O.
这实际上是一个非常好的想法。+1。 - Joey
@Peter,是的,那是一种方法。最终字符数量大致相同,但更易读。 - Simon Lindgren

2
这要看情况。您知道应用程序将在何处及如何使用,请考虑以下MSDN建议:
  1. 如果该值将显示给用户,请使用当前区域设置。请参阅System.Globalization.CultureInfo.CurrentCulture
  2. 如果该值将被存储并由软件访问(持久化到文件或数据库),请使用不变的区域设置。请参阅System.Globalization.CultureInfo.InvariantCulture
  3. 如果您不知道该值的目标位置,请要求数据使用者或提供者指定区域设置。

附注:我相信FxCop遵循第三个规则,让您自己指定正确的区域设置。


1
规则并不是您代码的唯一读者。如果您没有明确指定格式化文化,则维护开发人员将无法区分故意回退到默认格式化文化(在大多数情况下为CurrentCulture)或可能导致不正确格式化的遗漏。如果您不喜欢冗长,可以考虑使用像Peter O.提出的包装器方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接