105

C# 6 brings compiler support for interpolated string literals with syntax:

var person = new { Name = "Bob" };

string s = $"Hello, {person.Name}.";

This is great for short strings, but if you want to produce a longer string must it be specified on a single line?

With other kinds of strings you can:

    var multi1 = string.Format(@"Height: {0}
Width: {1}
Background: {2}",
        height,
        width,
        background);

Or:

var multi2 = string.Format(
    "Height: {1}{0}" +
    "Width: {2}{0}" +
    "Background: {3}",
    Environment.NewLine,
    height,
    width,
    background);

I can't find a way to achieve this with string interpolation without having it all one one line:

var multi3 = $"Height: {height}{Environment.NewLine}Width: {width}{Environment.NewLine}Background: {background}";

I realise that in this case you could use \r\n in place of Environment.NewLine (less portable), or pull it out to a local, but there will be cases where you can't reduce it below one line without losing semantic strength.

Is it simply the case that string interpolation should not be used for long strings?

Should we just string using StringBuilder for longer strings?

var multi4 = new StringBuilder()
    .AppendFormat("Width: {0}", width).AppendLine()
    .AppendFormat("Height: {0}", height).AppendLine()
    .AppendFormat("Background: {0}", background).AppendLine()
    .ToString();

Or is there something more elegant?

Drew Noakes
  • 284,599
  • 158
  • 653
  • 723
  • 7
    http://stackoverflow.com/questions/31764898/long-string-interpolation-lines-in-c6 – Ric Oct 20 '15 at 12:26
  • @DmytroShevchenko, I did consider doing so. However I wasn't sure about accepting yours as I watched you copy/paste the [top voted answer](http://stackoverflow.com/a/31764920/24874) from the link that Ric posted, then edit it to look different. That all happened within 5 minutes so the edits aren't visible. Your answer is technically correct, but I felt like you should have given credit. I would actually like to accept Ric's comment, but that's not possible. – Drew Noakes Oct 21 '15 at 14:45
  • @DrewNoakes your question has been marked as a duplicate of the question linked by Ric. Ric was the one who marked it, too. So there's no need to add yet another instance of that link to my answer. If you disagree, I would appreciate your reasoning. And of course I edited the code in my answer. Although, the reason was not to make it look different, but rather to match the example in your question. – Dmytro Shevchenko Oct 21 '15 at 14:59
  • @DmytroShevchenko see the site's footer: user contributions licensed under cc by-sa 3.0 with attribution required – Drew Noakes Oct 21 '15 at 15:06
  • @DrewNoakes Ha! That is a good argument! :) Edited my answer. – Dmytro Shevchenko Oct 21 '15 at 15:09
  • 3
    Voting to reopen. The supposed duplicate question asks something different and contrary (they want line breaks in source code but not the string). Moderators, read questions carefully before you close them! – Colonel Panic May 05 '16 at 14:50

3 Answers3

215

You can combine $ and @ together to get a multiline interpolated string literal:

string s =
$@"Height: {height}
Width: {width}
Background: {background}";

Source: Long string interpolation lines in C#6 (Thanks to @Ric for finding the thread!)

Community
  • 1
  • 1
Dmytro Shevchenko
  • 31,443
  • 6
  • 50
  • 66
  • 7
    I had tried this as @$ (reversed) and it didn't work so I figured they couldn't be combined. It didn't occur to me to try it the other way. – kencordero Feb 15 '17 at 15:37
  • 4
    Starting with C# 8.0, you can use the $ and @ tokens in any order: both $@"..." and @$"..." are valid interpolated verbatim strings. In earlier C# versions, the $ token must appear before the @ token. – hal9000 Mar 24 '20 at 15:30
12

I'd probably use a combination

var builder = new StringBuilder()
    .AppendLine($"Width: {width}")
    .AppendLine($"Height: {height}")
    .AppendLine($"Background: {background}");
thehennyy
  • 3,752
  • 1
  • 21
  • 29
sara
  • 3,381
  • 12
  • 30
  • could the downvoter give any insights? I don't see any issues with this, is there a problem? – sara Oct 20 '15 at 12:56
  • For the record I actually upvoted you. There may be cases where this is more readable. The only negative I can think of is that it's creating a few extra objects for the GC. – Drew Noakes Oct 21 '15 at 14:52
  • 3
    I think that is only a negative in exceptional cases where you have very limited resources or need to append thousands, if not millions of rows. I don't particularly like verbatim strings for formatting. It makes the layout of the text in the code file responsible for the appearance of the output. I prefer stringbuilder, it's more expressive. – sara Oct 21 '15 at 15:50
  • I agree about the formatting of verbatim strings being a bit ugly. `String.Concat` might also be an option here. – Drew Noakes Oct 21 '15 at 23:03
  • Definitely like concat more than verbatim. The nice thing about stringbuilder is that it takes care of doing linebreaks for you. I'd probably be OK with either one though. – sara Oct 22 '15 at 08:16
  • @sara I think your comment about using verbatim strings for formatting makes the layout of the text in the code file responsible for the appearance of the output." is a really great point! It made me rethink the approach I was about take on formatting a multiline string. I think maybe if you included that statement in your answer, it might have made down-voters consider why they were actually down voting instead of just not liking the answer or thinking that it didn't answer the OPs specific question (which it did) instead of answering the "spirit" of the question && emphasising code quality. – Adam Porad Oct 09 '19 at 18:09
  • they might have downvoted this since it doesn't produce a formattable string, for example it can't be used in `ExecuteSqlInterpolated` – Patrick Beynio Dec 02 '20 at 12:42
  • Performance of interpolated strings seems to be very good, much better than StringBuilder. – cskwg Mar 12 '21 at 07:03
7

Personally, I just add another interpolated string using string concatenation

For example

var multi  = $"Height     : {height}{Environment.NewLine}" +
             $"Width      : {width}{Environment.NewLine}" +
             $"Background : {background}";

I find that is easier to format and read.

This will have additional overhead compared to using $@" " but only in the most performance critical applications will this be noticeable. In memory string operations are extremely cheap compared to data I/O. Reading a single variable from the db will take hundreds of times longer in most cases.

Andrew Monteith
  • 107
  • 1
  • 3