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

时间:2015-08-18 15:39:16

标签: c# .net vb.net visual-studio-2015 string.format

Visual Studio 2015中的新字符串插值样式是:

Dim s = $"Hello {name}"

但如果我使用它,代码分析告诉我,我打破了CA1305: Specify IFormatProvider

在过去,我这样做了:

Dim s = String.Format(Globalization.CultureInfo.InvariantCulture, "Hello {0}", name)

但是如何用新风格来完成呢?

我必须提到我正在寻找.Net 4.5.2的解决方案(针对.Net 4.6 dcastro has the answer

3 个答案:

答案 0 :(得分:21)

您使用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进行编译,因为IFromattableFormattableString是旧版本中不存在的类。所以如果您定位旧版本的.NET框架,则无法在不触发错误的情况下使用插值语法。

除非你申请一点点破解(adapted to compile against 4.6 RTM from Jon Skeet's gistforked to my own account。)。只需在项目中添加一个类文件,其中包含:

  

更新

     

现在还有一个Nuget package available that will provide the same functionality to your project(感谢我把这个引起了我的注意@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);
        }
    }
}

见:

答案 1 :(得分:12)

如果您定位.NET Framework 4.6,则可以利用字符串插值可隐式转换为result = Braintree::Transaction.sale( :amount => '100.00', :payment_method_nonce => 'nonce-from-the-client', :options => { :submit_for_settlement => true } ) puts result.transaction.processor_response_code 这一事实:

Thomas Levesque的Customizing string interpolation in C# 6

  

此功能的一个鲜为人知的方面是内插字符串可以被视为FormattableStringString,具体取决于上下文。

IFormattable

答案 2 :(得分:2)

Microsoft使使用string interpolation和遵守CA1305: Specify IFormatProvider变得更加容易。

如果您使用的是C#6或更高版本,则可以访问using static指令。

此外,静态方法from typing import Sequence def ordered_contains(s1: Sequence, s2: Sequence) -> bool: ''' >>> ordered_contains('ahz', 'abhgz') True >>> ordered_contains('', 'asdlkjf') True >>> ordered_contains('lol', 'lofi') False ''' i = 0 for v in s1: try: i = s2.index(v, i) except ValueError: return False return True 可用于.NET Standard 1.3.NET Core 1.0.NET Framework 4.6及更高版本。将两者放在一起可以做到这一点:

FormattableString.Invariant

但是,如果您的目标是通过当前区域性进行插值,则.NET Core 3.0中将提出一种伴随的静态方法using static System.FormattableString; string name = Invariant($"Hello {name}"); (当前是预览版5):

FormattableString.CurrentCulture