Подтвердить что ты не робот

Интерполяция строк в Visual Studio 2015 и IFormatProvider (CA1305)

Новый стиль интерполяции строк в 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 имеет ответ)

4b9b3361

Ответ 1

Microsoft упростила использование интерполяции строк и соответствует CA1305: укажите IFormatProvider.

Если вы используете С# 6 или новее, у вас есть доступ к директиве using static.

Кроме того, статический метод FormattableString.Invariant доступен для .NET Standard 1.3, .NET Core 1.0 и .NET Framework 4.6 и более поздних FormattableString.Invariant. Соединение двух позволяет вам сделать это:

using static System.FormattableString;

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

Однако если ваша цель состоит в том, чтобы интерполяция выполнялась с использованием текущей культуры, то в .NET Core 3.0 (в настоящее время, Preview 5) предлагается сопутствующий статический метод FormattableString.CurrentCulture:

using static System.FormattableString;

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

Ответ 2

Вы должны использовать класс 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);

Необходимо выполнить компиляцию с Framework 4.6, поскольку IFromattable и FormattableString являются классами, которые не существуют в более старых версиях. Итак, , если вы ориентируетесь на более старые версии .NET framework, вы не можете использовать синтаксис интерполяции, не вызывая ошибки.

Если вы не примените небольшой взлом (адаптированный для компиляции с 4.6 RTM от метода Jon Skeet и раздвоенный на мою собственную учетную запись.). Просто добавьте файл класса в ваш проект, содержащий:

Update

Теперь доступен также пакет 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);
        }
    }
}

Смотрите:

Ответ 3

Если вы ориентируетесь на .NET Framework 4.6, вы можете воспользоваться тем фактом, что интерполяции строк неявно конвертируются в FormattableString:

Из Настройка интерполяции строк в С# 6 Томаса Левеска

Менее известный аспект этой функции заключается в том, что интерполированную строку можно рассматривать либо как String, либо как IFormattable, в зависимости от контекста.

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

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