Skip to content

BRO1138: A string literal should be a plain string when nothing needs more

A string literal uses $, @ or raw string quotes only when it needs them: $ for interpolations, @ for backslashes, quotes or line breaks, raw strings for quotes or several lines. Not a StyleCop rule (Roslynator RCS1214, RCS1192, RCS1262).

Example

Before

public class Messages
{
    public string Done() => $"Done";

    public string Folder() => @"logs";

    public string Title() => """Report""";

    public string Template() => $"Use {{name}} here";

    public string Path() => $@"C:\{{temp}}";
}

After

public class Messages
{
    public string Done() => "Done";

    public string Folder() => "logs";

    public string Title() => "Report";

    public string Template() => "Use {name} here";

    public string Path() => @"C:\{temp}";
}

Why

$ and @ tell the reader to look for interpolations and escapes. When there are none, they are noise, and a $ without holes hides the doubled {{/}} that only an interpolated string needs.

How the fix works

The whole simplification is one edit, so one dotnet format run is enough:

  • $"..." without interpolations: the $ goes and {{/}} become {/}. $@"..." (or @$"...") also loses the @ when the text has no backslash, "" or line break, else it stays a verbatim string.
  • @"..." without a backslash, "" or line break becomes "..." (also with u8).
  • A single-line raw string ("""...""", also u8 and an interpolated one without holes) without a backslash or quote becomes "...". A multi-line raw string with $ but no holes only loses the $s.

Not reported

  • Empty strings ($"", @""): BRO1106 turns them into string.Empty.
  • An interpolated string that isn't used as a string (or object): as a FormattableString, IFormattable or an interpolated string handler (Debug.Assert(x, $"..."), logging handlers) the plain string would call something else.
  • Interpolated strings with holes, including alignment and format specifiers.
  • Multi-line raw strings without $.

Compared with the SDK

The SDK has no rule for these: IDE0071 simplifies what is inside a hole ({x.ToString()} -> {x}), and nothing removes an unneeded $, @ or raw string.

Compared with StyleCop

StyleCop has no such rule. stylebro-migrate turns it off (see Rules beyond StyleCop).