Visual Studio 2015 和 IFormatProvider 中的字符串插值 (CA1305)
String Interpolation in Visual Studio 2015 and IFormatProvider (CA1305)
Visual Studio2015新的字符串插值样式是这样的:
Dim s = $"Hello {name}"
但是如果我使用这个代码分析告诉我我破坏了 CA1305: Specify IFormatProvider
以前我是这样做的:
Dim s = String.Format(Globalization.CultureInfo.InvariantCulture, "Hello {0}", name)
但是新样式怎么办呢?
我不得不提一下,我正在寻找 .Net 4.5.2 的解决方案(对于 .Net 4.6 )
如果您的目标是 .NET Framework 4.6,则可以利用字符串插值可以隐式转换为 FormattableString
:
来自 Customizing string interpolation in C# 6 作者:Thomas Levesque
A lesser known aspect of this feature is that an interpolated string can be treated either as a String
, or as an IFormattable
, depending on the context.
static string Invariant(FormattableString formattable)
{
return formattable.ToString(CultureInfo.InvariantCulture);
}
string text = Invariant($"{p.Name} was born on {p.DateOfBirth:D}");
您将使用 System.FormattableString
或 System.IFormattable
class:
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
是旧版本中不存在的 classes。因此,如果您的目标是较旧版本的 .NET 框架,则无法在不触发错误的情况下使用插值语法。
除非你应用一些技巧 (adapted to compile against 4.6 RTM from Jon Skeet's gist and forked to my own account)。只需将 class 文件添加到您的项目中,其中包含:
Update
There is now also a Nuget package available that will provide the same functionality to your project (thanks for bringing this to my attention @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);
}
}
}
参见:
我找到了一个包含 .
代码的 Nuget 包
Nuget 包 'StringInterpolationBridge' (source) 将此代码添加到每个项目。
Microsoft 使它更易于使用 string interpolation and comply with CA1305: Specify IFormatProvider。
如果您使用的是 C# 6 或更高版本,则可以访问 using static
指令。
此外,静态方法 FormattableString.Invariant
可用于 .NET Standard 1.3, .NET Core 1.0 and .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}");
Visual Studio2015新的字符串插值样式是这样的:
Dim s = $"Hello {name}"
但是如果我使用这个代码分析告诉我我破坏了 CA1305: Specify IFormatProvider
以前我是这样做的:
Dim s = String.Format(Globalization.CultureInfo.InvariantCulture, "Hello {0}", name)
但是新样式怎么办呢?
我不得不提一下,我正在寻找 .Net 4.5.2 的解决方案(对于 .Net 4.6
如果您的目标是 .NET Framework 4.6,则可以利用字符串插值可以隐式转换为 FormattableString
:
来自 Customizing string interpolation in C# 6 作者:Thomas Levesque
A lesser known aspect of this feature is that an interpolated string can be treated either as a
String
, or as anIFormattable
, depending on the context.
static string Invariant(FormattableString formattable)
{
return formattable.ToString(CultureInfo.InvariantCulture);
}
string text = Invariant($"{p.Name} was born on {p.DateOfBirth:D}");
您将使用 System.FormattableString
或 System.IFormattable
class:
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
是旧版本中不存在的 classes。因此,如果您的目标是较旧版本的 .NET 框架,则无法在不触发错误的情况下使用插值语法。
除非你应用一些技巧 (adapted to compile against 4.6 RTM from Jon Skeet's gist and forked to my own account)。只需将 class 文件添加到您的项目中,其中包含:
Update
There is now also a Nuget package available that will provide the same functionality to your project (thanks for bringing this to my attention @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);
}
}
}
参见:
我找到了一个包含
Nuget 包 'StringInterpolationBridge' (source) 将此代码添加到每个项目。
Microsoft 使它更易于使用 string interpolation and comply with CA1305: Specify IFormatProvider。
如果您使用的是 C# 6 或更高版本,则可以访问 using static
指令。
此外,静态方法 FormattableString.Invariant
可用于 .NET Standard 1.3, .NET Core 1.0 and .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}");