160

I've found that while string interpolation is really nice when applied to my existing code base's string Format calls, given the generally preferred column limit, the string rapidly becomes too long for a single line. Especially when the expressions being interpolated are complex. With a format string you have a list of variables that you can split into multiple lines.

var str = string.Format("some text {0} more text {1}",
    obj1.property,
    obj2.property);

Does anyone have any preferred means of breaking up these lines?

I suppose you could do something like:

var str = $"some text { obj1.property }" +
  $" more text { obj2.property };
Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
Jeremiah Gowdy
  • 5,476
  • 3
  • 21
  • 33
  • 1
    In my experience it's better to avoid interpolating complex expressions. Rather extract a variable in that case. If you do that, and you break up where you have newlines inside your strings, it will typically fit fine. – markijbema Aug 01 '15 at 18:49
  • 2
    I'm confused by this question. I just want a multiline `$""` that works like `@""` – Colonel Panic May 05 '16 at 14:12
  • 3
    Colonel Panic, the question is asking about how to break up long interpolation lines so we don't violate column width requirements, without introducing linefeeds in the string literal itself. $@"" is great but any newlines introduced into that will be in the string literal. – Jeremiah Gowdy May 05 '16 at 14:24
  • 1
    To support \t\r\n in $@ see the question https://stackoverflow.com/questions/51991713/long-string-interpolation-lines-in-c6-dont-support-tab-cr-and-lf/51991855#51991855 – M.Hassan Aug 23 '18 at 18:57
  • Actually, even `$"a: {a}" + $"b: {b}"` produces a simple string, preventing me from breaking a string interpolation on multiple lines. https://stackoverflow.com/questions/52788306/c-sharp-formattablestring-concatenation-for-multiline-interpolation got an answer for this too. – hsandt Mar 16 '19 at 23:02
  • Check C# 11 Raw string literals at https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#raw-string-literals. – Artur INTECH Feb 13 '23 at 07:06

5 Answers5

232

You can break the line into multiple lines, but I wouldn't say the syntax looks nice any more.

You need to use the $@ syntax to use an interpolated verbatim string, and you can place newlines inside the {...} parameters, like this:

string s = $@"This is all {
    10
    } going to be one long {
    DateTime.Now
    } line.";

The string above will not contain any newlines and will actually have content like this:

This is all 10 going to be one long 01.08.2015 23.49.47 line.

(note, norwegian format)

Now, having said that, I would not stop using string.Format. In my opinion some of these string interpolation expressions looks really good, but more complex ones starts to become very hard to read. Considering that unless you use FormattableString, the code will be compiled into a call to String.Format anyway, I would say keep going with String.Format where it makes sense.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • 1
    Solid answer. I am pretty sure `FormattableString` boils down to a call to `String.Format` too. – Alex Booker Aug 02 '15 at 06:19
  • 9
    This answer helped me figure out how to do the exact opposite of this. Thanks for the `$@""` syntax! – Bobson Oct 29 '15 at 16:49
  • 1
    @AlexBooker It's more complex than that. You can't do `FormattableString.Invarian($"Hello {name}" + \n "are you the owner of {pet}?");` because it merges the two interpolated strings into a single simple string. – ANeves Jan 30 '19 at 16:13
  • Newlines and tabs are respected in interpolated verbatim strings. Enter the following into the C# interactive window and the resulting string will be formatted:. `> var name = "Simon"; var templateName = "How to interpolate a verbatim string"; var now = DateTime.UtcNow;. var output = $@"Hi {name}, This template is a demo of {templateName}. It was ran at {now.ToString("o")}"; > output`. The output is `"Hi Simon,\r\nThis template is a demo of How to interpolate a verbatim string.\r\n\r\nIt was ran at 2020-01-24T15:49:35.6678353Z" ` – Enzoaeneas Jan 24 '20 at 16:01
  • 2
    @Enzoaeneas I think you overrated the formatting support in comments, but I understand and agree with what you're saying. – Lasse V. Karlsen Jan 24 '20 at 19:49
  • "Now, having said that, I would not stop using string.Format" It's a shame but the motivation for wanting to do multiline string interpolation is the same as why string.Format is not preferred, i.e. the longer the content, the more of a problem removing variables from their context is going to be. Pretty shoddy design by the c# team introducing this whitespace dependency into string interpolation. – Paul Childs Feb 05 '23 at 23:25
68

You can combine $ and @ together to get string interpolation and multi-line string literal:

var str = $@"some text { obj1.property }
     more text { obj2.property }";

But that will give you a NewLine character in between, so it might not be what you want.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
28

While OP asked for something else, I expect many people reading this question would like a multiline interpolated $"" that works like @"". To do that, use $@""

$@"Height: {height}
Width: {width}
Background: {background}"
Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
4

This is it:

var str = $"some text { obj1.property }" +
          $" more text { obj2.property }";

Note the second $ in the $"..." + $"..."

CallMeLaNN
  • 8,328
  • 7
  • 59
  • 74
  • 23
    Note that this will make two calls to String.Format and also create three strings in memory (Side A, Side B, and A+B) – Kevin Kalitowski Dec 18 '15 at 20:08
  • 2
    Wouldn’t this prevent you from using a `FormattableString` cast on the concatenated string? – binki Jul 12 '16 at 19:04
  • 4
    In many implementations today, running on a GHz CPU with Gb's of memory, an extra call and an additional string will not give you performance problems. Performance problems will be caused by e.g. using an algorithm of O(n2). I think it's unfair to downvote this guy. – Johan Franzén Nov 01 '19 at 10:14
0

I have used StringBuilder within overridden ToString() as an example.

    // return employee data
    public override string ToString()
    {
        StringBuilder buffer = new StringBuilder();
        buffer.AppendLine($"Number: {EmployeeNumber}");
        buffer.AppendLine($"Name: {EmployeeName}");
        buffer.AppendLine($"Address: {PostalAddress}");
        buffer.AppendLine($"Phone: {PhoneNumber}");
        buffer.AppendLine($"Age: {EmployeeAge}");
        buffer.AppendLine($"Gender: {EmployeeGender}");
        buffer.AppendLine($"Status: {EmployeeStatus}");
        buffer.AppendLine($"Manager: {EmployeeManager}");
        buffer.AppendLine($"Start: {EmployeeStartDate.ToShortDateString()}");
        return buffer.ToString();
    }
  • then why not **`buffer.AppendFormat("{0}Number: {1}", Environment.NewLine, EmployeeNumber);`** ??? – T.S. May 08 '18 at 23:18
  • 1
    If this was done a lot it would not perform well. You are doing an interpolation per line and the adding it to the string builder. You would be much better off just doing multiple append calls and adding the new line character before the start of the next item. Your current way uses up memory for each string and interpolation result that needs to be garbage collected. – Kevin Green Jan 21 '21 at 21:57