Visual Studio 2015中的字符串插值和IFormatProvider (CA1305)
本文关键字:IFormatProvider CA1305 插值 字符串 Studio 2015 Visual | 更新日期: 2023-09-27 18:08:37
Visual Studio 2015中新的字符串插值样式是:
Dim s = $"Hello {name}"
但是如果我使用这个代码分析告诉我我打破CA1305:指定IFormatProvider
过去我是这样做的:
Dim s = String.Format(Globalization.CultureInfo.InvariantCulture, "Hello {0}", name)
但是新款式怎么做呢?
我必须提到我正在寻找。net 4.5.2的解决方案(对于。net 4.6 dcastro有答案)
您将使用System.FormattableString
或System.IFormattable
类:
IFormattable ifs = (IFormattable)$"Hello, {name}";
System.FormattableString fss = $"Hello, {name}";
// pass null to use the format as it was used upon initialization above.
string ifresult = ifs.ToString(null, CultureInfo.InvariantCulture);
string fsresult = fss.ToString(CultureInfo.InvariantCulture);
你需要在Framework 4.6上编译,因为IFormattable
和FormattableString
是旧版本中不存在的类。所以如果你的目标是旧版本的。net框架,你不能使用插值语法而不触发错误。
除非你应用了一个小hack(改编自Jon Skeet的gist,以编译4.6 RTM,并分叉到我自己的帐户)。只需在项目中添加一个类文件,其中包含:
更新现在还有一个可用的Nuget包,它将为您的项目提供相同的功能(感谢您让我注意到@habakuk)。
install-package StringInterpolationBridge
或者,如果您希望在不向产品添加额外程序集的情况下实现相同的功能,请将以下代码添加到您的项目中:
namespace System.Runtime.CompilerServices
{
internal class FormattableStringFactory
{
public static FormattableString Create(string messageFormat, params object[] args)
{
return new FormattableString(messageFormat, args);
}
}
}
namespace System
{
internal class FormattableString : IFormattable
{
private readonly string messageFormat;
private readonly object[] args;
public FormattableString(string messageFormat, object[] args)
{
this.messageFormat = messageFormat;
this.args = args;
}
public override string ToString()
{
return string.Format(messageFormat, args);
}
public string ToString(string format, IFormatProvider formatProvider)
{
return string.Format(formatProvider, format ?? messageFormat, args);
}
public string ToString(IFormatProvider formatProvider)
{
return string.Format(formatProvider, messageFormat, args);
}
}
}
:
- https://msdn.microsoft.com/en-us/library/dn961160.aspx
如果您的目标是。net Framework 4.6,您可以利用字符串插入隐式转换为FormattableString
的事实:
选自Thomas Levesque在c# 6中定制字符串插值
这个特性的一个不太为人所知的方面是,内插字符串可以被视为
String
或IFormattable
,这取决于上下文。
static string Invariant(FormattableString formattable)
{
return formattable.ToString(CultureInfo.InvariantCulture);
}
string text = Invariant($"{p.Name} was born on {p.DateOfBirth:D}");
Microsoft已经使使用字符串插值变得更容易,并且符合CA1305:指定IFormatProvider.
如果你使用的是c# 6或更高版本,你可以访问using static
指令。
此外,静态方法FormattableString.Invariant
可用于。net Standard 1.3、。net Core 1.0和。net Framework 4.6及更高版本。将这两个组合在一起可以这样做:
using static System.FormattableString;
string name = Invariant($"Hello {name}");
然而,如果你的目标是通过当前文化来完成插值,那么在。net Core 3.0(目前,预览5)中提出了一个伴随的静态方法FormattableString.CurrentCulture
:
using static System.FormattableString;
string name = CurrentCulture($"Hello {name}");
我找到了一个Nuget-Package,它涵盖了jessehouwing在他的回答中提供的代码。
Nuget包'StringInterpolationBridge'(源代码)将此代码添加到每个项目中。