Ответ 1
FormattableString
- это новый тип в .NET 4.6, и компилятор будет использовать его только в том случае, если вы попытаетесь его использовать. Другими словами, тип интерполированного строкового литерала обычно string
- построен с string.Format
- но может быть FormattableString
(через FormattableStringFactory
), если вы попросите его.
A FormattableString
состоит из строки формата, которая будет передана в string.Format
(например, "Hello, {0}"
) и аргументов, которые будут переданы для ее форматирования. Крайне важно, чтобы эта информация была записана до форматирования.
Это позволяет вам соответствующим образом отрегулировать форматирование - наиболее часто для его реализации в инвариантной культуре, часто с помощью статического метода Invariant
.
Когда вы назначаете интерполированный строковый литерал переменной IFormattable
, которая также будет использовать FormattableString
. В IFormattable.ToString(string, CultureInfo)
реализация игнорирует первый аргумент в этом случае, который, по-видимому, объясняет, почему он использует явную реализацию интерфейса.
Пример кода:
using System;
using System.Globalization;
using System.Threading;
using static System.FormattableString;
class Test
{
static void Main()
{
var uk = CultureInfo.CreateSpecificCulture("en-GB");
Thread.CurrentThread.CurrentCulture = uk;
var germany = CultureInfo.CreateSpecificCulture("de-DE");
string now = $"Default: it is now {DateTime.UtcNow}";
Console.WriteLine(now); // UK format
IFormattable x = $"Specific: It is now {DateTime.UtcNow}";
Console.WriteLine(x.ToString("ignored", germany));
FormattableString y = $"FormattableString: It is now {DateTime.UtcNow}";
Console.WriteLine(FormattableString.Invariant(y));
// Via using static
Console.WriteLine(Invariant($"It is now {DateTime.UtcNow}"));
}
}
Примеры результатов:
Default: it is now 16/02/2016 07:16:21
Specific: It is now 16.02.2016 07:16:21
FormattableString: It is now 02/16/2016 07:16:21
It is now 02/16/2016 07:16:21