vb.net Visual Studio 2015 和 IFormatProvider (CA1305) 中的字符串插值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32076823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
String Interpolation in Visual Studio 2015 and IFormatProvider (CA1305)
提问by habakuk
The new string interpolation style in Visual Studio 2015 is this:
Visual Studio 2015 中新的字符串插值样式是这样的:
Dim s = $"Hello {name}"
But if I use this the code analysis tells me I break CA1305: Specify IFormatProvider
但是如果我使用它,代码分析告诉我我破坏了CA1305:Specify IFormatProvider
In the old times I did it like this:
在过去,我是这样做的:
Dim s = String.Format(Globalization.CultureInfo.InvariantCulture, "Hello {0}", name)
But how can it be done with the new style?
但是如何用新的风格做到这一点呢?
I have to mention that I'm looking for a solution for .Net 4.5.2 (for .Net 4.6 dcastro has the answer)
我不得不提一下,我正在寻找 .Net 4.5.2 的解决方案(对于 .Net 4.6 dcastro 有答案)
采纳答案by DavidRR
Microsoft has made it easier to use string interpolationand comply with CA1305: Specify IFormatProvider.
Microsoft 使字符串插值的使用变得更容易并符合CA1305:指定 IFormatProvider。
If you are using C# 6 or later, you have access to the using staticdirective.
如果您使用的是 C# 6 或更高版本,则可以访问该using static指令。
In addition, the static method FormattableString.Invariantis available for .NET Standard 1.3, .NET Core 1.0and .NET Framework 4.6and later. Putting the two together allows you to do this:
此外,静态方法FormattableString.Invariant可用于.NET Standard 1.3、.NET Core 1.0和.NET Framework 4.6及更高版本。将两者放在一起可以让你做到这一点:
using static System.FormattableString;
string name = Invariant($"Hello {name}");
If, however, your goal is for the interpolation to be done via the current culture, then a companion static method FormattableString.CurrentCultureis proposed in .NET Core 3.0(currently, Preview 5):
但是,如果您的目标是通过当前区域性完成插值,则.NET Core 3.0(当前为预览版 5)中FormattableString.CurrentCulture提出了一个配套的静态方法:
using static System.FormattableString;
string name = CurrentCulture($"Hello {name}");
回答by jessehouwing
You'd use the System.FormattableStringor System.IFormattableclass:
你会使用System.FormattableStringorSystem.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);
You need to be compiling against Framework 4.6, as the IFormattableand FormattableStringare classes which do not exist in older versions. So if you're targeting older versions of the .NET frameworkyou can't use the interpolation syntax without triggering the error.
您需要针对 Framework 4.6 进行编译,因为IFormattable和FormattableString是旧版本中不存在的类。因此,如果您的目标是旧版本的 .NET 框架,则不能在不触发错误的情况下使用插值语法。
Unless you apply a little hack (adapted to compile against 4.6 RTM from Jon Skeet's gistand forked to my own account.). Just add a class file to your project containing:
除非你应用一些小技巧(根据 Jon Skeet 的要点改编为针对 4.6 RTM 编译并分叉到我自己的帐户。)。只需将一个类文件添加到您的项目中,其中包含:
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
更新
现在还有一个Nuget 包可以为您的项目提供相同的功能(感谢您提请我注意 @habakuk)。
install-package StringInterpolationBridge
Or if you want to achieve the same thing without adding an additional assembly to your product add the following code to your project:
或者,如果您想在不向产品中添加额外程序集的情况下实现相同的目标,请将以下代码添加到您的项目中:
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);
}
}
}
See:
看:
回答by dcastro
If you're targeting the .NET Framework 4.6, you can take advantage of the fact that string interpolations are implicitly convertible to FormattableString:
如果您的目标是 .NET Framework 4.6,则可以利用字符串插值可隐式转换为FormattableString:
From Customizing string interpolation in C# 6by Thomas Levesque
来自Thomas Levesque在 C# 6 中自定义字符串插值
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.
此功能的一个鲜为人知的方面是,根据上下文,可以将内插字符串视为 a
String或 anIFormattable。
static string Invariant(FormattableString formattable)
{
return formattable.ToString(CultureInfo.InvariantCulture);
}
string text = Invariant($"{p.Name} was born on {p.DateOfBirth:D}");
回答by habakuk
I have found a Nuget-Package that covers the code that jessehouwing presented in his answer.
我找到了一个 Nuget-Package,其中涵盖了jessehouwing 在他的回答中提供的代码。
The Nuget package 'StringInterpolationBridge' (source) adds this code to every project.
Nuget 包“StringInterpolationBridge”(源代码)将此代码添加到每个项目中。

