1399

Is there an easy way to create a multiline string literal in C#?

Here's what I have now:

string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";

I know PHP has

<<<BLOCK

BLOCK;

Does C# have something similar?

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
Chet
  • 21,375
  • 10
  • 40
  • 58
  • 2
    There are no line breaks in your example. Do you want them? – weiqure Jul 08 '09 at 20:08
  • 12
    No. I only wanted multiple lines for visibility/code cleanliness reasons. – Chet Jul 08 '09 at 20:10
  • 10
    In that case, verbatim strings contain the line breaks. You can use @"...".Replace(Environment.NewLine,"") if you like. – weiqure Jul 08 '09 at 20:13
  • 14
    You should consider binding the `42` as a parameter, especially if it comes from user input, to avoid SQL injection. – Jens Mühlenhoff Oct 24 '13 at 09:14
  • 3
    @weiqure: Environment.NewLine does not necessarily reflect the line breaks in the string as the line breaks are taken as they occur in the source code. So one can write the code even with different line breaks on each line that all differ from what Environment.NewLine says on the target system! – mmmmmmmm Jan 06 '21 at 06:00

14 Answers14

2082

You can use the @ symbol in front of a string to form a verbatim string literal:

string query = @"SELECT foo, bar
FROM table
WHERE id = 42";

You also do not have to escape special characters when you use this method, except for double quotes as shown in Jon Skeet's answer.

Max Yankov
  • 12,551
  • 12
  • 67
  • 135
John Rasch
  • 62,489
  • 19
  • 106
  • 139
  • 127
    if your string contains double-quotes ("), you can escape them like so: "" ( thats two double-quote characters) – Muad'Dib Jul 08 '09 at 20:09
  • 12
    Is there a way of doing the above without it creating new lines? I have a really long piece of text that I'd like to see wrapped in in the IDE without having to use the plus ("hi " + "there"). – noelicus Dec 12 '12 at 12:48
  • 4
    @noelicus - not really, but you could workaround that by using weiqure's technique above of: `@"my string".Replace(Environment.NewLine, "")` – John Rasch Dec 12 '12 at 15:39
  • MonoDevelop-Unity chokes on % here. – Jonny Mar 02 '15 at 03:30
  • 1
    `@` actually makes C# treat a string literal the way VB treats string literals. – Achilles Apr 02 '15 at 20:47
  • 2
    How about combination of `@` and new C# operator that is `$`? – Afshar Mohebi Nov 03 '15 at 10:53
  • 19
    @afsharm You can use $@"text" – Patrick McDonald Apr 29 '16 at 15:48
  • Here is an example for XML string, pay attention to the double quates: @" – Kevin .NET Aug 17 '17 at 18:28
  • 2
    This answer is incorrect. Your query string ends up containing newlines, which is not what was asked for. I believe the correct answer is "no, you cannot do this in C#". See Carco Loco's answer. I will grant you it is a bit unclear what he means by wanting a "multi-line string literal", but his "here's what I have now" should dispell any doubts as to what his intention is. – TamaMcGlinn Dec 21 '18 at 16:02
  • In C++ you would end each line with a backslash to achieve a string literal without newlines, whose definition spans multiple lines. Which is what I believe OP was asking for. – TamaMcGlinn Dec 21 '18 at 16:03
701

It's called a verbatim string literal in C#, and it's just a matter of putting @ before the literal. Not only does this allow multiple lines, but it also turns off escaping. So for example you can do:

string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";

This includes the line breaks (using whatever line break your source has them as) into the string, however. For SQL, that's not only harmless but probably improves the readability anywhere you see the string - but in other places it may not be required, in which case you'd either need to not use a multi-line verbatim string literal to start with, or remove them from the resulting string.

The only bit of escaping is that if you want a double quote, you have to add an extra double quote symbol:

string quote = @"Jon said, ""This will work,"" - and it did!";
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
238

As a side-note, with C# 6.0 you can now combine interpolated strings with the verbatim string literal:

string camlCondition = $@"
<Where>
    <Contains>
        <FieldRef Name='Resource'/>
        <Value Type='Text'>{(string)parameter}</Value>
    </Contains>
</Where>";
Riegardt Steyn
  • 5,431
  • 2
  • 34
  • 49
  • 15
    Cool, I did not know about this until now. If anyone is interested: The $ thingy is called "Interpolated Strings" and you can read about it in detail here: https://msdn.microsoft.com/en-us/library/dn961160.aspx – Hauke P. Feb 19 '16 at 23:15
  • tx, fixed the wording – Riegardt Steyn Feb 20 '16 at 18:36
  • 5
    I assume a literal curly brace then must be doubled, e.g.`$@"{{example literal text { fooString }. }}"` This may confuse some because Angular, React, and Vue.js use the opposite convention. – Patrick Szalapski May 21 '18 at 19:23
  • This is a cool find. Although, if your interpolated string values call out to methods - eg: `{date.ToString("yyyy-mm-dd")}` You may want to consider the @dav_i answer as the interpolation is cleaner that way without having to mess with double quotes – AndrewGentry Sep 08 '20 at 22:31
144

The problem with using string literal I find is that it can make your code look a bit "weird" because in order to not get spaces in the string itself, it has to be completely left aligned:

    var someString = @"The
quick
brown
fox...";

Yuck.

So the solution I like to use, which keeps everything nicely aligned with the rest of your code is:

var someString = String.Join(
    Environment.NewLine,
    "The",
    "quick",
    "brown",
    "fox...");

And of course, if you just want to logically split up lines of an SQL statement like you are and don't actually need a new line, you can always just substitute Environment.NewLine for " ".

dav_i
  • 27,509
  • 17
  • 104
  • 136
  • 3
    Much cleaner, thanks. Also, String.Concat works similarly and doesn't require a separator. – Seth Jan 13 '15 at 19:24
  • 12
    While ugly, the first version *requires no code to run*. The second option obviously has a run-time overhead to concatenate the separate strings. – iCollect.it Ltd Mar 03 '16 at 11:58
  • Thanks for this, but it can't be helped in the case of verbatim in attributes. Like : [Tooltip(@"Very long string.....")] which you could not run any codes. I was planning to put verbatim because the code looks ugly as a single line string argument when I am working with full screen editor. But then verbatim adds other invisible characters to the string itself so I could not find any other way. – 5argon May 24 '17 at 10:23
  • 1
    While this will compile ok, and it looks nicer, it **fails** to pass code validation because it is vulnerable to SQL injection attack. You are not allowed to construct any query string at run-time. It must be a constant. – John Henckel Oct 03 '18 at 15:17
  • I like this method as well, because it makes interpolation cleaner. Imagine if you wanted to do something like `"The", "Quick", $"{fox.color}", "Fox"` – AndrewGentry Sep 08 '20 at 22:26
107

One other gotcha to watch for is the use of string literals in string.Format. In that case you need to escape curly braces/brackets '{' and '}'.

// this would give a format exception
string.Format(@"<script> function test(x) 
      { return x * {0} } </script>", aMagicValue)
// this contrived example would work
string.Format(@"<script> function test(x) 
      {{ return x * {0} }} </script>", aMagicValue)
Martin Clarke
  • 5,636
  • 7
  • 38
  • 58
  • 14
    And what difference does it make? With or without "@" you have to double "{{" to get "{" as printable character, it is matter of String.Format, not string content. – greenoldman Aug 27 '11 at 13:38
  • 12
    It's a notable gotcha for people who want to put Javascript code in a string, which may be done more often in verbatim string literals than regular strings. – Ed Brannin Mar 15 '13 at 14:25
  • 2
    In the new C# 6.0, you can use an indexed property operator together with the verbatim string literal (like this $@"Value is {this.Value}";) – Riegardt Steyn Aug 13 '15 at 06:54
  • 2
    @Heliac I think you mean interpolated strings can also be literal with that syntax. var query = $@" select foo, bar from table where id = {id} "; – brianary Nov 01 '17 at 15:09
86

Why do people keep confusing strings with string literals? The accepted answer is a great answer to a different question; not to this one.

I know this is an old topic, but I came here with possibly the same question as the OP, and it is frustrating to see how people keep misreading it. Or maybe I am misreading it, I don't know.

Roughly speaking, a string is a region of computer memory that, during the execution of a program, contains a sequence of bytes that can be mapped to text characters. A string literal, on the other hand, is a piece of source code, not yet compiled, that represents the value used to initialize a string later on, during the execution of the program in which it appears.

In C#, the statement...

 string query = "SELECT foo, bar"
 + " FROM table"
 + " WHERE id = 42";

... does not produce a three-line string but a one liner; the concatenation of three strings (each initialized from a different literal) none of which contains a new-line modifier.

What the OP seems to be asking -at least what I would be asking with those words- is not how to introduce, in the compiled string, line breaks that mimick those found in the source code, but how to break up for clarity a long, single line of text in the source code without introducing breaks in the compiled string. And without requiring an extended execution time, spent joining the multiple substrings coming from the source code. Like the trailing backslashes within a multiline string literal in javascript or C++.

Suggesting the use of verbatim strings, nevermind StringBuilders, String.Joins or even nested functions with string reversals and what not, makes me think that people are not really understanding the question. Or maybe I do not understand it.

As far as I know, C# does not (at least in the paleolithic version I am still using, from the previous decade) have a feature to cleanly produce multiline string literals that can be resolved during compilation rather than execution.

Maybe current versions do support it, but I thought I'd share the difference I perceive between strings and string literals.

UPDATE:

(From MeowCat2012's comment) You can. The "+" approach by OP is the best. According to spec the optimization is guaranteed: http://stackoverflow.com/a/288802/9399618

Carvo Loco
  • 2,068
  • 13
  • 21
  • 3
    The confusion some (including myself) may have had looking at the original question is that the here-doc format (shell, php, perl, ...) includes the newlines. So if the OP is comparing to PHP's heredoc, then including the newlines shouldn't have been an issue. – Tanktalus Mar 12 '18 at 16:01
  • Exactly. As far as I know, your answer "no, you cannot do this in C#" is correct. – TamaMcGlinn Dec 21 '18 at 15:53
  • 1
    I was told that in Java, such a concatenated string will become a single string literal in the compiled bytecode. Maybe dot Net do so as well? – Meow Cat 2012 Jul 23 '19 at 13:00
  • 5
    You can. The "+" approach by OP is the best. According to spec the optimization is guaranteed: https://stackoverflow.com/a/288802/9399618 Still you're one of the few understanding the question. Would it be possible to remove or fold potentially misleading but accepted answers? – Meow Cat 2012 Jul 23 '19 at 13:08
  • 2
    Thanks for the hint, @MeowCat2012. Looking at some decompiled code, it seems that is indeed the case. – Carvo Loco Jul 24 '19 at 16:46
65

Add multiple lines : use @

string query = @"SELECT foo, bar
FROM table
WHERE id = 42";

Add String Values to the middle : use $

string text ="beer";
string query = $"SELECT foo {text} bar ";

Multiple line string Add Values to the middle: use $@

string text ="Customer";
string query = $@"SELECT foo, bar
FROM {text}Table
WHERE id = 42";
Isanka Thalagala
  • 1,625
  • 3
  • 16
  • 32
30

In C# 11 [2022], you will be able to use Raw String literals. The use of Raw String Literals makes it easier to use " characters without having to write escape sequences.

Solution for OP:

string query1 = """
    SELECT foo, bar
    FROM table
    WHERE id = 42
    """;

string query2 = """
    SELECT foo, bar
    FROM table
    WHERE id = 42
    and name = 'zoo'
    and type = 'oversized "jumbo" grand'
    """;

More details about Raw String Literals

See the Raw String Literals GitHub Issue for full details; and Blog article C# 11 Preview Updates – Raw string literals, UTF-8 and more!

Kind Contributor
  • 17,547
  • 6
  • 53
  • 70
  • Just adding to this ([here](https://stackoverflow.com/a/76313043/7111561)) you can also combine this with interpolation – derHugo May 23 '23 at 09:09
24

You can use @ and "".

        string sourse = @"{
        ""items"":[
        {
            ""itemId"":0,
            ""name"":""item0""
        },
        {
            ""itemId"":1,
            ""name"":""item1""
        }
        ]
    }";
vovkas
  • 1,091
  • 10
  • 21
15

I haven't seen this, so I will post it here (if you are interested in passing a string you can do this as well.) The idea is that you can break the string up on multiple lines and add your own content (also on multiple lines) in any way you wish. Here "tableName" can be passed into the string.

    private string createTableQuery = "";

    void createTable(string tableName)
    {

         createTableQuery = @"CREATE TABLE IF NOT EXISTS
                ["+ tableName  + @"] (
               [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
               [Key] NVARCHAR(2048)  NULL, 
               [Value] VARCHAR(2048)  NULL
                                )";
    }
RobertHana
  • 195
  • 1
  • 2
  • 11
    pretty dangerous I'd say: easy for somebody to make a sql-injections that way. – Kai Nov 10 '14 at 10:35
  • 6
    It's fine as long as you know that all your variables (if any!) in your query string come from code constants or another safe source -- e.g., `createTable("MyTable");` In any case, the OP's question was about how to enter multiline string literals directly in code, not how to construct database queries per se. :) – dbeachy1 Feb 28 '15 at 05:09
  • 2
    should probably use a string builder, especially if the number of pluses (+) is a lot. – galdin Jul 09 '15 at 12:49
8

Yes, you can split a string out onto multiple lines without introducing newlines into the actual string, but it aint pretty:

string s = $@"This string{
string.Empty} contains no newlines{
string.Empty} even though it is spread onto{
string.Empty} multiple lines.";

The trick is to introduce code that evaluates to empty, and that code may contain newlines without affecting the output. I adapted this approach from this answer to a similar question.

There is apparently some confusion as to what the question is, but there are two hints that what we want here is a string literal not containing any newline characters, whose definition spans multiple lines. (in the comments he says so, and "here's what I have" shows code that does not create a string with newlines in it)

This unit test shows the intent:

    [TestMethod]
    public void StringLiteralDoesNotContainSpaces()
    {
        string query = "hi"
                     + "there";
        Assert.AreEqual("hithere", query);
    }

Change the above definition of query so that it is one string literal, instead of the concatenation of two string literals which may or may not be optimized into one by the compiler.

The C++ approach would be to end each line with a backslash, causing the newline character to be escaped and not appear in the output. Unfortunately, there is still then the issue that each line after the first must be left aligned in order to not add additional whitespace to the result.

There is only one option that does not rely on compiler optimizations that might not happen, which is to put your definition on one line. If you want to rely on compiler optimizations, the + you already have is great; you don't have to left-align the string, you don't get newlines in the result, and it's just one operation, no function calls, to expect optimization on.

TamaMcGlinn
  • 2,840
  • 23
  • 34
  • 1
    Creative. However it seems that (not confirmed) this would be treated as format string and may or may not be optimized. On the other hand the "+" approach by OP is the best. According to spec the optimization is guaranteed: https://stackoverflow.com/a/288802/9399618 – Meow Cat 2012 Jul 23 '19 at 13:11
4

If you don't want spaces/newlines, string addition seems to work:

var myString = String.Format(
  "hello " + 
  "world" +
  " i am {0}" +
  " and I like {1}.",
  animalType,
  animalPreferenceType
);
// hello world i am a pony and I like other ponies.

You can run the above here if you like.

rattray
  • 5,174
  • 1
  • 33
  • 27
  • 2
    One (inadvertently demonstrated) flaw with this approach is that you have to be very careful to include spaces where you want them. I'd recommend a more consistent approach than I took (eg; always at the beginning of the line). – rattray May 13 '15 at 08:13
  • string + string is just what OP started with, though. – TamaMcGlinn Dec 21 '18 at 16:15
2

In addition to Kind Contributor's answer about Raw String literals

You can now also combine this with string interpolation!

See e.g. Raw String literal

var someValue = 23.45f;
    
var json = $$"""
           {
               "summary": "text",
               "value" : {{someValue}},
           };
           """;
                   
Console.WriteLine(json);

will result in

{
    "summary": "text",
    "value" : 23.45,
};

(fiddle)

derHugo
  • 83,094
  • 9
  • 75
  • 115
0
using System;

namespace Demo {

   class Program {

      static void Main(string[] args) {
         string str = @"Welcome User,
         Kindly wait for the image to
         load";

         Console.WriteLine(str);
      }
   }
}

Output

Welcome User,
Kindly wait for the image to
load
m.myalkin
  • 1,128
  • 1
  • 10
  • 18