Строки (Руководство по программированию на C#)

Строка является объектом типа String, значением которого является текст. По сути, текст хранится в виде последовательной доступной только для чтения коллекции объектов Char. В конце строки на языке C# отсутствует символ, заканчивающийся на NULL; поэтому строка C# может содержать любое число внедренных символов NULL ("\0"). Свойство Length строки представляет число объектов Char, содержащихся в этой строке, а не число символов Юникода. Для доступа к отдельным точкам в строке кода Юникода используется объект StringInfo object.

string илиSystem.String

В C# ключевое слово string является псевдонимом свойства String. Поэтому String и string эквивалентны, и пользователи могут использовать любое наиболее предпочтительное для них соглашение по наименованию. Класс String предоставляет множество методов для безопасного создания, обработки и сравнения строк. Кроме того, язык C# перегружает некоторые операторы для упрощения наиболее употребительных операций со строками. Дополнительные сведения о ключевом слове см. в разделе string (Справочник по C#). Дополнительные сведения о типе и его методах см. в разделе String.

Объявление и инициализация строк

Объявление и инициализацию строк можно выполнять различными способами, как показано в следующем примере:

// 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);

Обратите внимание, что для создания строкового объекта оператор new не используется, за исключением, за исключением случаев инициализации строки массивом символов.

Инициализация строки значением константы Empty приводит к созданию нового объекта String, строка которого имеет нулевую длину. Строковый литерал нулевой длины представляется как "". При инициализации строк значением Empty вместо null снижается вероятности возникновения NullReferenceException. Используйте статический метод IsNullOrEmpty(String), чтобы проверить значение строки перед попыткой обращения к ней.

Неизменность строковых объектов

Строковые объекты являются неизменяемыми: после создания их нельзя изменить. Все методы String и операторы C#, которые, как можно было бы представить, изменяют строку, в действительности возвращают результаты в новый строковый объект. В следующем примере, когда содержимое строк s1 и s2 объединяется в одну строку, две исходные строки не изменяются. Оператор += создает новую строку с объединенным содержимым. Этот новый объект присваивается переменной s1, а исходный объект, который был присвоен строке s1, освобождается для сборки мусора, поскольку ни одна переменная не содержит ссылку на него.

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.

Поскольку "изменением" строки в действительности является созданием новой строки, необходима предосторожность при создании ссылок на строки. Если создать ссылку на строку, а затем "изменить" исходную строку, то ссылка будет по-прежнему указывать на исходный объект, а не на новый объект, который был создан при изменении строки. Это поведение демонстрируется в следующем коде.

string s1 = "Hello ";
string s2 = s1;
s1 += "World";

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

Дополнительные сведения о том, как создавать новые строки, основанные на таких изменениях как операции поиска и замены исходной строки, см. в разделе Практическое руководство. Изменение содержимого строки (Руководство по программированию в C#).

Правильные и буквальные строковые литералы

Правильные строковые литералы используются, если нужно внедрить escape-символы, предоставляемые языком C#, как показано в следующем примере.

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

Буквальные строковые литералы используются для удобства и удобства чтения, если текст строки содержит символы обратной косой черты, например в путях к файлу. Поскольку в буквальных строках сохраняются символы новой строки как часть текста строки, они могут использоваться для инициализации многострочных строк. Для встраивания кавычек в буквальную строку используются двойные кавычки. В следующем примере показаны примеры наиболее типичного использования буквальных строк.

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."

Escape-последовательности строк

Escape-последовательность

Имя символа

Кодировка Юникода

\'

Одинарная кавычка

0x0027

\"

Двойная кавычка

0x0022

\\

Обратная косая черта

0x005C

\0

Null

0x0000

\a

ALERT

0x0007

\b

Backspace

0x0008

\f

FORM FEED

0x000C

\n

Новая строка

0x000A

\r

Возврат каретки

0x000D

\t

Горизонтальная табуляция

0x0009

\U

Escape-последовательность Юникода для пар символов-заместителей.

\Unnnnnnnn

\u

Escape-последовательность Юникода

\u0041 = "A"

\v

Вертикальная табуляция

0x000B

\x

Escape-последовательность Юникода аналогична "\u", за исключением строк с переменной длиной.

\x0041 = "A"

Примечание

Во время компиляции буквальные строки преобразуются в обычные строки со всеми теми же escape-последовательностями.Поэтому, если в окне отладчика просматривается буквальная строка, будут видны escape-символы, добавленные компилятором, а не буквальная версия из исходного кода.Например, буквальная строка @"C:\files.txt" в окне отладчика будет выглядеть как "C:\\files.txt".

Строки форматов

Строкой формата является строка, содержимое которой можно определить динамически во время выполнения. Строка формата создается при помощи статического метода Format и внедренных местозаполнителей в скобках, которые во время выполнения будут заменены другими значениями. В следующем примере используется строка формата для вывода результатов каждой итерации цикла.

class FormatString
{
    static void Main()
    {
        // Get user input.
        System.Console.WriteLine("Enter a number");
        string input = System.Console.ReadLine();

        // Convert the input string to an int. 
        int j;
        System.Int32.TryParse(input, out j);

        // Write a different string each iteration. 
        string s;
        for (int i = 0; i < 10; i++)
        {
            // A simple format string with no alignment formatting.
            s = System.String.Format("{0} times {1} = {2}", i, j, (i * j));
            System.Console.WriteLine(s);
        }

        //Keep the console window open in debug mode.
        System.Console.ReadKey();
    }
}

Одна перегрузка метода WriteLine в качестве параметра принимает строку формата. Поэтому можно просто внедрить строковый литерал формата без явного вызова метода. Но если используется метод WriteLine для отображения вывода отладочных данных в окно Вывод среды Visual Studio, необходимо явно вызвать метод Format, поскольку WriteLine принимает только строку, а не строку формата. Дополнительные сведения о строках форматах см. в разделе Типы форматирования в .NET Framework.

Подстроки

Подстрокой является последовательность символов, содержащихся в строке. Метод Substring используется для создания новой строки на основании части исходной строки. Одно или несколько вхождений подстроки можно найти с использованием метода IndexOf. Метод Replace используется для замены всех вхождений заданной подстроки новой строкой. Так же, как и метод Substring, метод Replace фактически возвращает новую строку и не изменяет исходную строку. Дополнительные сведения см. в разделах Практическое руководство. Поиск строк с помощью строковых методов (Руководство по программированию в C#) и Практическое руководство. Изменение содержимого строки (Руководство по программированию в C#).

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

Доступ к отдельным знакам

Нотацию массива можно использовать со значением индекса, чтобы получить доступ только для чтения к отдельным символам, как в следующем примере:

string s5 = "Printing backwards";

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

Если методы String не предоставляют функциональных возможностей, которые необходимы для изменения отдельных символов в строке, можно использовать объект StringBuilder, чтобы изменить отдельные символы "на месте", а затем создать новую строку для сохранения результатов с использованием методов StringBuilder. В следующем примере предположим, что необходимо изменить исходную строку определенным образом, а затем сохранить результаты для дальнейшего использования.

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?            

Строки с нулевыми значениями и пустые строки

Пустая строка — это экземпляр объекта String, содержащий 0 знаков. Пустые строки часто используются в различных сценариях программирования, представляя пустое текстовое поле. Для пустых строк можно вызывать методы, потому что такие строки являются допустимыми объектами String. Пустые строки инициализируются следующим образом:

string s = String.Empty;

Строки со значениями null (с нулевыми значениями), напротив, не ссылаются на экземпляр объекта String, любая попытка вызвать метод на строка со значением null приведет к ошибке NullReferenceException. Однако такие строки можно использовать в операциях объединения и сравнения с другими строками. В следующих примерах показаны некоторые случаи, в которых ссылка на строку со значением null вызывает либо не вызывает исключение:

static void Main()
{
    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);
}

Использование StringBuilder для быстрого создания строк

Операции со строками в .NET в высокой степени оптимизированы и в большинстве случаев значительно не снижают производительность. Однако в некоторых случаях, например, в непрерывных циклах, выполняющихся сотни и тысячи раз, операции со строками могут влиять на производительность. Класс StringBuilder создает строковый буфер, который позволяет повысить производительность, если в программе обрабатывается много строк. Класс StringBuilder также позволяет заново присваивать отдельные знаки, что не поддерживается встроенным строковым типом данных. Например, данный код заменяет содержимое строки без создания новой строки:

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

//Outputs Cat: the ideal pet

В этом примере объект StringBuilder используется для создания строки из набора числовых типов:

class TestStringBuilder
{
    static void Main()
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

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

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

        System.Console.WriteLine(sb);  // displays 9123456789
    }
}

Строки, методы расширения и LINQ

Поскольку тип String реализует IEnumerable, можно использовать методы расширения, определенные в классе Enumerable на строках. Чтобы избежать загромождения рабочего пространства, эти методы исключены из IntelliSense для типа String, но тем не менее, они доступны. Можно также использовать выражения запросов LINQ на строках. Дополнительные сведения см. в разделе LINQ и строки.

Связанные разделы

Раздел

Описание

Практическое руководство. Изменение содержимого строки (Руководство по программированию в C#)

Содержит пример кода, с помощью которого показывается, как можно изменить содержимое строк.

Практическое руководство. Сцепка нескольких строк (Руководство по программированию на C#)

Иллюстрирует, как использовать оператор + и класс Stringbuilder для объединения строк во время компиляции и во время выполнения.

Практическое руководство. Сравнение строк (Руководство по программированию в C#)

Показано, как выполнять порядковые сравнения строк.

Практическое руководство. Разделение строк (Руководство по программированию в C#)

Содержит пример кода, с помощью которого показывается, как можно использовать метод String.Split для выполнения анализа строк.

Практическое руководство. Поиск строк с помощью строковых методов (Руководство по программированию в C#)

Содержит описание использования конкретных методов для выполнения поиска по строкам.

Практическое руководство. Поиск строк с помощью регулярных выражений (Руководство по программированию в C#)

Содержит описание использования регулярных выражений для выполнения поиска по строкам.

Практическое руководство. Определение представления числового значения в строке (Руководство по программированию в C#)

Показано, как безопасно выполнить синтаксический анализ строки, чтобы посмотреть, имеет ли она допустимое числовое значение.

Практическое руководство. Преобразование строки в значение типа "DateTime" (Руководство по программированию в C#)

Показано, как преобразовать строку, такую как "24/01/2008", в объект DateTime.

Базовые операции со строками в .NET Framework

Ссылки на разделы, в которых методы String и StringBuilder используются для выполнения базовых операций на строками.

Анализ строк в .NET Framework

Вставка знаков или пробелов в строку.

Сравнение строк в .NET Framework

Содержит сведения о том, как выполняется сравнение строк, и примеры на языках C# и Visual Basic.

Использование класса StringBuilder в .NET Framework

Создание и изменение динамических строковых объектов с помощью класса StringBuilder.

LINQ и строки

Содержит сведения о том, как выполняются различные операции со строками с помощью запросов LINQ.

Руководство по программированию на C#

Содержит ссылки на разделы, содержащие конструкции программирования на языке C#.

Важная глава книги

Дополнительные сведения о переменных IN Начало Visual c# 2010