Råa strängliteraler

Tip

Den här artikeln är en del av avsnittet Grunderna för utvecklare som redan känner till minst ett programmeringsspråk och lär sig C#. Om du inte har använt programmering tidigare börjar du med självstudierna Komma igång först. Fullständig grammatik finns i språkreferensen.

Kommer du från ett annat språk? C#-råa stränglitteraler fyller samma roll som Pythons och Rusts r"..."-strängar, Javas textblock ("""...""") och de backtick-avgränsade mallsträngarna i JavaScript, TypeScript och Go. C#-syntaxen är närmast Java textblock, med extra regler för avgränsare och interpolering med variabel längd.

En rå sträng avgränsas med tre eller flera dubbla citationstecken. Mellan avgränsarna tolkas varje tecken bokstavligt. Citattecken och omvänt snedstreck behöver inte komma ifrån, och nya streck bevaras som skrivna. Använd råsträngar för alla strängar som innehåller citattecken, omvänt snedstreck eller flera rader: JSON, XML, SQL, reguljära uttryck, filsökvägar och kodexempel.

Varning

En rå strängliteral gör SQL enklare att läsa, men det gör inte SQL säkrare. Sammanfoga eller interpolera aldrig användarinmaterade värden i ett SQL-kommando. Den metoden öppnar programmet för SQL-inmatning. Använd parametriserade kommandon i stället: DbCommand.CreateParameter med DbParameterCollection.Add eller hjälphjälparna på högre nivå i Entity Framework Core och Dapper. Samma försiktighet gäller för andra inmatningsbenägna format som gränssnittskommandon, LDAP-filter och HTML.

En literal som innehåller citattecken och omvänt snedstreck

En vanlig literal behöver escapes för " och \. En verbatimsträng måste fortfarande använda "" för att innehålla ett citattecken. En råliteral behöver ingetdera:

// Same JSON value, three ways:
string regular  = "{ \"name\": \"Ada\", \"path\": \"C:\\\\src\" }";
string verbatim = @"{ ""name"": ""Ada"", ""path"": ""C:\\src"" }";
string raw      = """{ "name": "Ada", "path": "C:\\src" }""";

Console.WriteLine(regular  == raw);   // True
Console.WriteLine(verbatim == raw);   // True

Varje formulär genererar samma sträng, men den råa versionen läser exakt som den JSON den representerar.

Enradiga råsträngar

De inledande och avslutande avgränsarna består vardera av minst tre dubbla citattecken, och den avslutande avgränsaren måste använda lika många citattecken som den inledande avgränsaren. Innehållet finns mellan dem på samma rad. Citationstecken och omvänt snedstreck i innehållet är bokstavliga:

// A raw string literal starts and ends with at least three quotes.
// Inside, " and \ are literal — no escaping required.
string message = """She said "hi" and left.""";
string regex   = """\d{3}-\d{4}""";

Console.WriteLine(message);   // She said "hi" and left.
Console.WriteLine(regex);     // \d{3}-\d{4}

En rå sträng med en rad får inte vara tom mellan dess avgränsare. Det kan sluta med ett dubbelt citattecken, men det kan inte börja med ett. Kompilatorn behandlar ett inledande dubbelt citationstecken som ett ytterligare inledande avgränsningstecken. Om innehållet måste börja med ett citattecken ska du i stället använda en råsträngliteral med flera rader, vilket placerar innehållet på en egen rad där ett inledande citattecken är otvetydigt.

Flerradiga råsträngar

För innehåll med flera rader avslutar den inledande avgränsare linjen och den avslutande avgränsare startar sin egen. Precis som med enradiga råsträngar är avgränsaren tre eller flera dubbla citationstecken, och den avslutande avgränsaren måste innehålla lika många citationstecken som den inledande avgränsaren. Tre citationstecken är det vanliga fallet, men du kan använda fyra, fem eller fler när själva innehållet innehåller en följd av """. Allt mellan de två avgränsarna är värdet för strängen, exakt som skrivet:

// The opening """ and closing """ each sit on their own line.
// The content between them is the value, exactly as written.
string sql = """
    SELECT id, name
    FROM customers
    WHERE active = 1
    """;

Console.WriteLine(sql);

Den nya rad omedelbart efter öppningen """ och den nya rad omedelbart före stängningen """ är inte en del av värdet. De är avgränsande blanktecken. På samma sätt tar kompilatorn bort alla blanksteg till vänster om stängningen """ från varje innehållsrad, så att du kan dra in literalen så att den matchar dess omslutande kodblock utan att indraget visas i strängen. I nästa avsnitt beskrivs den här regeln i detalj.

Om själva innehållet innehåller en följd av """, använder du fyra eller fler citationstecken som avgränsare. Antalet avgränsare behöver bara vara större än den längsta följden av citattecken i innehållet. Se Råa strängliteraler (språkreferens) för alla reglerna.

Indrag: den avslutande avgränsaren bestämmer marginalen

Kolumnen för stängningen """ definierar en vänstermarginal. Kompilatorn tar bort blanktecken fram till den kolumnen från varje rad med innehåll. Med den här regeln kan du dra in literalen så att den matchar den omgivande koden utan att förorena värdet:

// The column of the closing """ sets a left margin.
// Whitespace up to that column is stripped from every content line.
string xml = """
        <order id="42">
            <item>book</item>
        </order>
        """;

// First content line begins at column 0 of the value:
Console.WriteLine(xml);
/* Output:
   <order id="42">
       <item>book</item>
   </order>
 */

Om en innehållsrad har färre inledande blankstegstecken än den avslutande avgränsarens kolumn rapporterar kompilatorn ett fel. Håll alla innehållsrader indragna minst lika mycket som den avslutande """.

Obehandlade interpolerade strängar

Lägg till ett $ prefix i en råsträng för att aktivera interpolering. Uttrycken i {} hål utvärderas och deras resultat infogas i värdet:

// A single $ before """ enables interpolation: single { and } mark a hole.
// Inside a single-$ raw string, literal braces aren't allowed — use $$ when
// the content also contains literal { or }.
string name = "Ada";
int    score = 95;

string report = $"""
    Player:  {name}
    Score:   {score}
    Updated: {DateTime.UtcNow:yyyy-MM-dd}
    """;

Console.WriteLine(report);

Om ditt interpolerade innehåll också behöver de bokstavliga tecknen { eller }, se Obearbetade stränglitteraler (språkreferens).

När du ska välja vilken literal

Använd en rå strängliteral när innehållet innehåller citattecken, omvänt snedstreck eller flera rader. Resultatet blir kortare att läsa igenom, lättare att klistra in i eller ut ur och fritt från escape-sekvensbuggar.

Använd en vanlig strängliteral för korta värden på en rad utan citattecken eller bakstreck, som namn, meddelanden och formatplatshållare.

Använd endast en ordagrann strängliteral (@"...") när du arbetar med befintlig kod som använder dem. För ny kod täcker råa strängar alla de fall som verbatim-strängar täcker, med renare syntax för inbäddade citattecken.

Se även