Strängar och strängliteraler

En sträng är ett objekt av typen String vars värde är text. Internt lagras texten som en sekventiell skrivskyddad samling Char objekt. Det finns inget null-avslutande tecken i slutet av en C#-sträng. Därför kan en C#-sträng innehålla valfritt antal inbäddade null-tecken (\0). Egenskapen Length för en sträng representerar antalet Char objekt som den innehåller, inte antalet Unicode-tecken. Använd -objektet för att komma åt enskilda Unicode-kodpunkter i en sträng StringInfo .

string jämfört med System.String

I C# är nyckelordet string ett alias för String. String Därför och string är likvärdiga, oavsett om det rekommenderas att använda det angivna aliaset string eftersom det fungerar även utan using System;. Klassen String innehåller många metoder för att på ett säkert sätt skapa, manipulera och jämföra strängar. Dessutom överbelastar C#-språket vissa operatorer för att förenkla vanliga strängåtgärder. Mer information om nyckelordet finns i sträng. Mer information om typen och dess metoder finns i String.

Deklarera och initiera strängar

Du kan deklarera och initiera strängar på olika sätt, som du ser i följande exempel:

// Declare without initializing.
string message1;

// Initialize to null.
string message2 = null;

// Initialize as an empty string.
// Use the Empty constant instead of the literal "".
string message3 = System.String.Empty;

// Initialize with a regular string literal.
string oldPath = "c:\\Program Files\\Microsoft Visual Studio 8.0";

// Initialize with a verbatim string literal.
string newPath = @"c:\Program Files\Microsoft Visual Studio 9.0";

// Use System.String if you prefer.
System.String greeting = "Hello World!";

// In local variables (i.e. within a method body)
// you can use implicit typing.
var temp = "I'm still a strongly-typed System.String!";

// Use a const string to prevent 'message4' from
// being used to store another string value.
const string message4 = "You can't get rid of me!";

// Use the String constructor only when creating
// a string from a char*, char[], or sbyte*. See
// System.String documentation for details.
char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);

Du använder inte den nya operatorn för att skapa ett strängobjekt, förutom när du initierar strängen med en matris med tecken.

Initiera en sträng med konstantvärdet Empty för att skapa ett nytt String objekt vars sträng är av noll längd. Strängliteralrepresentationen av en sträng med noll längd är "". Genom att initiera strängar med Empty värdet i stället för null kan du minska risken för att ett NullReferenceException inträffar. Använd den statiska IsNullOrEmpty(String) metoden för att verifiera värdet för en sträng innan du försöker komma åt den.

Oföränderlighet för strängar

Strängobjekt är oföränderliga: de kan inte ändras när de har skapats. String Alla metoder och C#-operatorer som verkar ändra en sträng returnerar faktiskt resultatet i ett nytt strängobjekt. I följande exempel, när innehållet i s1 och s2 sammanfogas för att bilda en enda sträng, är de två ursprungliga strängarna oförändrade. Operatorn += skapar en ny sträng som innehåller det kombinerade innehållet. Det nya objektet tilldelas till variabeln s1, och det ursprungliga objektet som tilldelades släpps s1 för skräpinsamling eftersom ingen annan variabel innehåller en referens till det.

string s1 = "A string is more ";
string s2 = "than the sum of its chars.";

// Concatenate s1 and s2. This actually creates a new
// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;

System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.

Eftersom en sträng "ändring" faktiskt är en ny sträng skapas, måste du vara försiktig när du skapar referenser till strängar. Om du skapar en referens till en sträng och sedan "ändrar" den ursprungliga strängen fortsätter referensen att peka på det ursprungliga objektet i stället för det nya objektet som skapades när strängen ändrades. Följande kod illustrerar det här beteendet:

string str1 = "Hello ";
string str2 = str1;
str1 += "World";

System.Console.WriteLine(str2);
//Output: Hello

Mer information om hur du skapar nya strängar som baseras på ändringar, till exempel sök- och ersättningsåtgärder på den ursprungliga strängen, finns i Så här ändrar du stränginnehåll.

Strängliteraler med citat

Strängliteraler med citattecken börjar och slutar med ett enda dubbelt citattecken (") på samma rad. Strängliteraler med citattecken passar bäst för strängar som får plats på en enda rad och som inte innehåller några escape-sekvenser. En strängliteral med citattecken måste bädda in escape-tecken, som du ser i följande exempel:

string columns = "Column 1\tColumn 2\tColumn 3";
//Output: Column 1        Column 2        Column 3

string rows = "Row 1\r\nRow 2\r\nRow 3";
/* Output:
    Row 1
    Row 2
    Row 3
*/

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge

Ordagranna strängliteraler

Ordagranna strängliteraler är mer praktiska för flerradssträngar, strängar som innehåller omvänt snedstreck eller inbäddade dubbla citattecken. Ordagranna strängar bevarar nya radtecken som en del av strängtexten. Använd dubbla citattecken för att bädda in ett citattecken i en ordagrann sträng. I följande exempel visas några vanliga användningsområden för ordagranna strängar:

string filePath = @"C:\Users\scoleridge\Documents\";
//Output: C:\Users\scoleridge\Documents\

string text = @"My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...";
/* Output:
My pensive SARA ! thy soft cheek reclined
    Thus on mine arm, most soothing sweet it is
    To sit beside our Cot,...
*/

string quote = @"Her name was ""Sara.""";
//Output: Her name was "Sara."

Råsträngliteraraler

Från och med C# 11 kan du använda råa strängliteraler för att enklare skapa strängar som är flerradssträngar eller använda tecken som kräver escape-sekvenser. Råsträngliteraraler tar bort behovet av att någonsin använda escape-sekvenser. Du kan skriva strängen, inklusive blankstegsformatering, hur du vill att den ska visas i utdata. En rå strängliteral:

  • Börjar och slutar med en sekvens med minst tre dubbla citattecken ("""). Du får fler än tre tecken i följd att starta och avsluta sekvensen för att stödja strängliteraler som innehåller tre (eller fler) upprepade citattecken.
  • Råsträngliteraler med en rad kräver inledande och avslutande citattecken på samma rad.
  • Strängliteraler med flera rader kräver både inledande och avslutande citattecken på sin egen rad.
  • I strängliteraler med flera rader tas alla blanksteg till vänster om de avslutande citattecknarna bort.

Följande exempel visar dessa regler:

string singleLine = """Friends say "hello" as they pass by.""";
string multiLine = """
    "Hello World!" is typically the first program someone writes.
    """;
string embeddedXML = """
       <element attr = "content">
           <body style="normal">
               Here is the main text
           </body>
           <footer>
               Excerpts from "An amazing story"
           </footer>
       </element >
       """;
// The line "<element attr = "content">" starts in the first column.
// All whitespace left of that column is removed from the string.

string rawStringLiteralDelimiter = """"
    Raw string literals are delimited 
    by a string of at least three double quotes,
    like this: """
    """";

Följande exempel visar de kompilatorfel som rapporterats baserat på dessa regler:

// CS8997: Unterminated raw string literal.
var multiLineStart = """This
    is the beginning of a string 
    """;

// CS9000: Raw string literal delimiter must be on its own line.
var multiLineEnd = """
    This is the beginning of a string """;

// CS8999: Line does not start with the same whitespace as the closing line
// of the raw string literal
var noOutdenting = """
    A line of text.
Trying to outdent the second line.
    """;

De två första exemplen är ogiltiga eftersom strängliteraler med flera rader kräver inledande och avslutande citatsekvens på sin egen rad. Det tredje exemplet är ogiltigt eftersom texten dras ut från den avslutande citatsekvensen.

Du bör överväga råa strängliteraler när du genererar text som innehåller tecken som kräver escape-sekvenser när du använder citatsträngsliteraler eller ordagranna strängliteraler. Råsträngliteraler blir enklare för dig och andra att läsa eftersom de kommer att likna utdatatexten närmare. Tänk dig till exempel följande kod som innehåller en sträng med formaterad JSON:

string jsonString = """
{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2019-08-01T00:00:00-07:00",
    "2019-08-02T00:00:00-07:00"
  ],
  "TemperatureRanges": {
    "Cold": {
      "High": 20,
      "Low": -10
    },
    "Hot": {
      "High": 60,
      "Low": 20
    }
            },
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}
""";

Jämför texten med motsvarande text i vårt exempel på JSON-serialisering, som inte använder den här nya funktionen.

Escape-sekvenser för strängar

Escape-sekvens Teckennamn Unicode-kodning
\' Enkelt citattecken 0x0027
\" Dubbelt citattecken 0x0022
\\ Omvänt snedstreck 0x005C
\0 Null 0x0000
\a Varning 0x0007
\b Backsteg 0x0008
\f Formulärfeed 0x000C
\n Ny rad 0x000A
\r Vagnretur 0x000D
\t Vågrät flik 0x0009
\v Lodrät flik 0x000B
\u Unicode-escape-sekvens (UTF-16) \uHHHH (intervall: 0000 - FFFF; exempel: \u00E7 = "ç")
\U Unicode-escape-sekvens (UTF-32) \U00HHHHHH (intervall: 000000 - 10FFFF; exempel: \U0001F47D = "👽")
\x Unicode-escape-sekvens som liknar "\u" förutom med variabel längd \xH[H][H][H] (intervall: 0 - FFFF; exempel: \x00E7 eller \x0E7 = \xE7 "ç")

Varning

När du använder \x escape-sekvensen och anger mindre än 4 hexadecimala siffror, om tecknen som följer direkt efter escape-sekvensen är giltiga hexadecimala siffror (dvs. 0-9, A-F och a-f), tolkas de som en del av escape-sekvensen. Skapar till exempel \xA1 "¡", som är kodpunkten U+00A1. Men om nästa tecken är "A" eller "a" tolkas escape-sekvensen istället som att vara \xA1A och producera "ਚ", som är kodpunkten U+0A1A. Om du anger alla fyra hexadecimala siffror (t.ex. \x00A1 ) förhindras eventuell feltolkning.

Anteckning

Vid kompilering konverteras ordagranna strängar till vanliga strängar med samma escape-sekvenser. Om du visar en ordagrann sträng i visningsfönstret för felsökningsprogrammet visas därför escape-tecknen som har lagts till av kompilatorn, inte den ordagranna versionen från källkoden. Den ordagranna strängen @"C:\files.txt" visas till exempel i visningsfönstret som "C:\\files.txt".

Formatera strängar

En formatsträng är en sträng vars innehåll bestäms dynamiskt vid körning. Formatsträngar skapas genom inbäddning av interpolerade uttryck eller platshållare inuti klammerparenteser i en sträng. Allt inom klammerparenteserna ({...}) matchas till ett värde och utdata som en formaterad sträng vid körning. Det finns två metoder för att skapa formatsträngar: stränginterpolation och sammansatt formatering.

Stränginterpolation

Interpolerade strängar är tillgängliga i C# 6.0 och senare och identifieras av $ specialtecknet och innehåller interpolerade uttryck inom klammerparenteser. Om du inte har använt stränginterpolation tidigare kan du läsa den interaktiva självstudien Stränginterpolation – C# för en snabb översikt.

Använd stränginterpolation för att förbättra kodens läsbarhet och underhållbarhet. Stränginterpolation uppnår samma resultat som metoden, men förbättrar användarvänligheten och den infogade tydligheten String.Format .

var jh = (firstName: "Jupiter", lastName: "Hammon", born: 1711, published: 1761);
Console.WriteLine($"{jh.firstName} {jh.lastName} was an African American poet born in {jh.born}.");
Console.WriteLine($"He was first published in {jh.published} at the age of {jh.published - jh.born}.");
Console.WriteLine($"He'd be over {Math.Round((2018d - jh.born) / 100d) * 100d} years old today.");

// Output:
// Jupiter Hammon was an African American poet born in 1711.
// He was first published in 1761 at the age of 50.
// He'd be over 300 years old today.

Från och med C# 10 kan du använda stränginterpolation för att initiera en konstant sträng när alla uttryck som används för platshållare också är konstanta strängar.

Från och med C# 11 kan du kombinera råa strängliteraler med stränginterpolationer. Du startar och avslutar formatsträngen med tre eller fler dubbla citattecken. Om utdatasträngen { ska innehålla tecknet eller } kan du använda extra $ tecken för att ange hur många { tecken som } ska starta och avsluta en interpolering. Alla sekvenser med färre { tecken eller } tecken ingår i utdata. I följande exempel visas hur du kan använda funktionen för att visa avståndet för en punkt från ursprunget och placera punkten inom klammerparenteser:

int X = 2;
int Y = 3;

var pointMessage = $$"""The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y)}} from the origin.""";

Console.WriteLine(pointMessage);
// Output:
// The point {2, 3} is 3.605551275463989 from the origin.

Sammansatt formatering

String.Format använder platshållare i klammerparenteser för att skapa en formatsträng. Det här exemplet resulterar i utdata som liknar stränginterpoleringsmetoden som används ovan.

var pw = (firstName: "Phillis", lastName: "Wheatley", born: 1753, published: 1773);
Console.WriteLine("{0} {1} was an African American poet born in {2}.", pw.firstName, pw.lastName, pw.born);
Console.WriteLine("She was first published in {0} at the age of {1}.", pw.published, pw.published - pw.born);
Console.WriteLine("She'd be over {0} years old today.", Math.Round((2018d - pw.born) / 100d) * 100d);

// Output:
// Phillis Wheatley was an African American poet born in 1753.
// She was first published in 1773 at the age of 20.
// She'd be over 300 years old today.

Mer information om hur du formaterar .NET-typer finns i Formateringstyper i .NET.

Delsträngar

En delsträng är en sekvens med tecken som finns i en sträng. Substring Använd metoden för att skapa en ny sträng från en del av den ursprungliga strängen. Du kan söka efter en eller flera förekomster av en delsträng med hjälp IndexOf av metoden . Replace Använd metoden för att ersätta alla förekomster av en angiven delsträng med en ny sträng. Precis som Substring metoden Replace returnerar faktiskt en ny sträng och ändrar inte den ursprungliga strängen. Mer information finns i Så här söker du efter strängar och Så här ändrar du stränginnehåll.

string s3 = "Visual C# Express";
System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"

System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"

// Index values are zero-based
int index = s3.IndexOf("C");
// index = 7

Åtkomst till enskilda tecken

Du kan använda matrisnotation med ett indexvärde för att hämta skrivskyddad åtkomst till enskilda tecken, som i följande exempel:

string s5 = "Printing backwards";

for (int i = 0; i < s5.Length; i++)
{
    System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"

String Om metoderna inte ger den funktionalitet som du måste ha för att ändra enskilda tecken i en sträng kan du använda ett StringBuilder -objekt för att ändra de enskilda tecknen "på plats" och sedan skapa en ny sträng för att lagra resultaten med hjälp StringBuilder av metoderna. I följande exempel förutsätter vi att du måste ändra den ursprungliga strängen på ett visst sätt och sedan lagra resultatet för framtida användning:

string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);

for (int j = 0; j < sb.Length; j++)
{
    if (System.Char.IsLower(sb[j]) == true)
        sb[j] = System.Char.ToUpper(sb[j]);
    else if (System.Char.IsUpper(sb[j]) == true)
        sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?

Null-strängar och tomma strängar

En tom sträng är en instans av ett System.String objekt som innehåller noll tecken. Tomma strängar används ofta i olika programmeringsscenarier för att representera ett tomt textfält. Du kan anropa metoder för tomma strängar eftersom de är giltiga System.String objekt. Tomma strängar initieras på följande sätt:

string s = String.Empty;

En null-sträng refererar däremot inte till en instans av ett System.String objekt och försök att anropa en metod för en null-sträng orsakar en NullReferenceException. Du kan dock använda null-strängar i sammanfognings- och jämförelseåtgärder med andra strängar. I följande exempel visas några fall där en referens till en null-sträng gör och inte orsakar ett undantagsfel:

string str = "hello";
string nullStr = null;
string emptyStr = String.Empty;

string tempStr = str + nullStr;
// Output of the following line: hello
Console.WriteLine(tempStr);

bool b = (emptyStr == nullStr);
// Output of the following line: False
Console.WriteLine(b);

// The following line creates a new empty string.
string newStr = emptyStr + nullStr;

// Null strings and empty strings behave differently. The following
// two lines display 0.
Console.WriteLine(emptyStr.Length);
Console.WriteLine(newStr.Length);
// The following line raises a NullReferenceException.
//Console.WriteLine(nullStr.Length);

// The null character can be displayed and counted, like other chars.
string s1 = "\x0" + "abc";
string s2 = "abc" + "\x0";
// Output of the following line: * abc*
Console.WriteLine("*" + s1 + "*");
// Output of the following line: *abc *
Console.WriteLine("*" + s2 + "*");
// Output of the following line: 4
Console.WriteLine(s2.Length);

Använda stringBuilder för att snabbt skapa strängar

Strängåtgärder i .NET är mycket optimerade och påverkar i de flesta fall inte prestandan avsevärt. Men i vissa scenarier, till exempel åtsittande loopar som körs många hundra eller tusentals gånger, kan strängåtgärder påverka prestandan. Klassen StringBuilder skapar en strängbuffert som ger bättre prestanda om programmet utför många strängmanipuleringar. Med strängen StringBuilder kan du också omtilldela enskilda tecken, något som den inbyggda strängdatatypen inte stöder. Den här koden ändrar till exempel innehållet i en sträng utan att skapa en ny sträng:

System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
//Outputs Cat: the ideal pet

I det här exemplet används ett StringBuilder -objekt för att skapa en sträng från en uppsättning numeriska typer:

var sb = new StringBuilder();

// Create a string composed of numbers 0 - 9
for (int i = 0; i < 10; i++)
{
    sb.Append(i.ToString());
}
Console.WriteLine(sb);  // displays 0123456789

// Copy one character of the string (not possible with a System.String)
sb[0] = sb[9];

Console.WriteLine(sb);  // displays 9123456789

Strängar, tilläggsmetoder och LINQ

String Eftersom typen implementerar IEnumerable<T>kan du använda tilläggsmetoderna som definierats i Enumerable klassen på strängar. För att undvika visuell oreda undantas dessa metoder från IntelliSense för String typen, men de är tillgängliga ändå. Du kan också använda LINQ-frågeuttryck på strängar. Mer information finns i LINQ och Strängar.