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有答案)

Visual Studio 2015中的字符串插值和IFormatProvider (CA1305)

您将使用System.FormattableStringSystem.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上编译,因为IFormattableFormattableString是旧版本中不存在的类。所以如果你的目标是旧版本的。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中定制字符串插值

这个特性的一个不太为人所知的方面是,内插字符串可以被视为StringIFormattable,这取决于上下文。

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'(源代码)将此代码添加到每个项目中。