web-dev-qa-db-ja.com

Visual Studio 2015およびIFormatProvider(CA1305)での文字列補間

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が答えを持っています

29
habakuk

Microsoftは 文字列補間 を使いやすくし、 CA1305:IFormatProviderを指定する に準拠しています。

C#6以降を使用している場合、 using static ディレクティブ。

さらに、静的メソッドFormattableString.Invariant。NET Standard 1.。NET Core 1. および 。NET Framework 4.6 以降で使用できます。 2つを組み合わせると、これを行うことができます。

using static System.FormattableString;

string name = Invariant($"Hello {name}");

ただし、現在のカルチャを介して補間を実行することが目的である場合は、関連する静的メソッドFormattableString.CurrentCulture。NET Core 3. で提案されています(現在、プレビュー5):

using static System.FormattableString;

string name = CurrentCulture($"Hello {name}");
2
DavidRR

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);

IFromattableFormattableStringは古いバージョンには存在しないクラスであるため、Framework 4.6に対してコンパイルする必要があります。したがって、古いバージョンの.NETフレームワークをターゲットにしている場合、エラーをトリガーせずに補間構文を使用することはできません。

あなたが少しハックを適用しない限り( 4.6に対してコンパイルするように適応RTM Jon Skeet's Gistから および 自分のアカウントにフォークされた 。)。以下を含むクラスファイルをプロジェクトに追加します。

更新

プロジェクトに同じ機能を提供する利用可能な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);
        }
    }
}

見る:

21
jessehouwing

.NET Framework 4.6をターゲットにしている場合は、文字列補間が暗黙的にFormattableStringに変換できるという事実を利用できます。

From C#6での文字列補間のカスタマイズ by Thomas Levesque

この機能のあまり知られていない側面は、補間された文字列は、コンテキストに応じてStringまたはIFormattableとして処理できることです。

static string Invariant(FormattableString formattable)
{
    return formattable.ToString(CultureInfo.InvariantCulture);
}

string text = Invariant($"{p.Name} was born on {p.DateOfBirth:D}");
12
dcastro

jessehouwingが彼の回答で示した のコードをカバーするNuget-Packageを見つけました。

Nugetパッケージ 'StringInterpolationBridge'( source )は、このコードをすべてのプロジェクトに追加します。

4
habakuk