## Why is this an issue?

In order to produce a formatted string, both `string.Create` and either `FormattableString.Invariant` or `FormattableString.CurrentCulture` can be used. However, `string.Create` rents array buffers from `ArrayPool<char>` making it more performant, as well as preventing unnecessary allocations and future stress on the Garbage Collector.

This applies to .NET versions after .NET 6, when these `string.Create` overloads were introduced.

### What is the potential impact?

We measured a significant improvement both in execution time and memory allocation. For more details see the `Benchmarks` section from the `More info` tab.

## How to fix it

Replace calls to `FormattableString.CurrentCulture` or `FormattableString.Invariant` with calls to `string.Create(CultureInfo.CurrentCulture, …​)` or `string.Create(CultureInfo.InvariantCulture, …​)` respectively.

### Code examples

#### Noncompliant code example

    string Interpolate(string value) =>
        FormattableString.Invariant($"Value: {value}");

    string Interpolate(string value) =>
        FormattableString.CurrentCulture($"Value: {value}");

#### Compliant solution

    string Interpolate(string value) =>
        string.Create(CultureInfo.InvariantCulture, $"Value: {value}");

    string Interpolate(string value) =>
        string.Create(CultureInfo.CurrentCulture, $"Value: {value}");

## Resources

### Documentation

- string.Create
- FormattableString.Invariant
- FormattableString.CurrentCulture

### Articles & blog posts

- Compilation of interpolated strings

### Benchmarks

The results were generated by running the following snippet with BenchmarkDotNet:

Method | Runtime | Mean | Standard Deviation | Allocated
--- | --- | --- | --- | ---
StringCreate | .NET 7.0 | 152.5 ms | 3.09 ms | 83.92 MB
FormattableString | .NET 7.0 | 191.8 ms | 6.92 ms | 198.36 MB

#### Glossary

- Mean
- Standard Deviation
- Allocated

The results were generated by running the following snippet with BenchmarkDotNet:

    int Value = 42;
    DateTime Now = DateTime.UtcNow;

    [Params(1_000_000)]
    public int N;

    [Benchmark]
    public void StringCreate()
    {
        for (int i = 0; i < N; i++)
        {
            _ = string.Create(CultureInfo.InvariantCulture, $"{Now}: Value is {Value}");
        }
    }

    [Benchmark]
    public void FormattableStringInvariant()
    {
        for (int i = 0; i < N; i++)
        {
            _ = FormattableString.Invariant($"{Now}: Value is {Value}");
        }
    }

Hardware configuration:

    BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2728/22H2/2022Update)
    11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores
    .NET SDK=7.0.203
      [Host]   : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
      .NET 7.0 : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2