Specifying locale for string interpolation in C#6 (Roslyn CTP6)
C 6中的字符串插值允许我写:
1 2
| decimal m = 42.0m;
string x = $"The value is {m}"; |
但是,字符串格式化的一个非常常见的用例是指定用于格式化值的区域设置。假设我需要在上面的格式化操作中使用InvariantCulture,它的语法是什么?
这次讨论表明我应该能够做到:
1
| string x = INV($"The value is {m}"); |
其中inv定义为
1 2 3 4
| public static string INV(IFormattable formattable)
{
return formattable.ToString(null, System.Globalization.CultureInfo.InvariantCulture);
} |
但是,这不起作用。它会编译,但在启动时,它会让我的程序挂在cmd.exe中——就像我假设调用的klr.exe一样,挂起(编译器错误?)
这是VS15 CTP 6中的ASP.NET 5控制台项目。
- @Keithhill字符串插值的默认值是当前区域性不是不变的。:(
- @Aaronstainback是的,谢谢。我后来注意到了,但忘了回来更正我的评论。
- @亚伦:那样的话,你有没有解释我为什么会犯这个错误:(VS2015中的C Framwork 4.6项目):CA1305 (Because the behavior of 'string.Format(string, object, object)' could vary based on the current user's locale settings, replace this call in 'Function()' with a call to 'string.Format(IFormatProvider, string, params object[])'. If the result of 'string.Format(IFormatProvider, string, params object[])' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter[...]。
- @efloh与使用不指定区域性信息的string.Format重载时会得到代码分析错误的原因相同。此代码分析规则的要点是强制您显式指定区域性信息,因为开发人员很容易忽略在需要时将其标记为不变量(或错误地假定不变量是默认区域性)。
- 好吧,这是有道理的。在这种情况下,我们需要一个很酷的语法来指定插入字符串的区域性,例如$(CultureInfo.CurrentCulture)"my interpolated string"或至少当前(..)与现有inv(…)类似。
你所拥有的应该是有用的。这是正确的语法。在"system.formattablestring"抽象类上还有一个方便的方法,它与建议的"inv"helper方法具有相同的效果。
1 2 3
| using static System.FormattableString;
...
string x = Invariant($"The value is {m}"); |
- 如果这对你不起作用,请仔细检查一下你是否有using static System.FormattableString——尽管上面有明确的说明,我还是设法错过了它。)
我终于明白了。事实证明,编译器特性依赖于两种类型:System.FormattableString和System.Runtime.CompilerServices.FormattableStringFactory。我的项目没有这些功能——我想他们可能还没有进入CTP6的所有平台。
这显然使编译器按照描述挂起。一旦我从corecrl代码中提取了这两种类型的代码并将其添加到我的项目中,我的代码就会如预期的那样工作。
这是通过插入测试的代码注释计算出来的。正在提供源的hooray:-)
- 你在哪里找到这些组件?我使用的是.NET 4.5.2,我试图引用它们,但我看不到它们可供引用。
- 根据msdn.microsoft.com/en-us/library/…,它首先出现在4.6中。