В отличие от других ссылочных типов операции, проверяющие эквивалентность, сравнивают значения строк, а не ссылки. Эти операции выполняются как над значимыми типами.
Бинарная операция "+" сцепляет две строки, приписывая вторую строку к хвосту первой.
Возможность взятия индекса при работе со строками отражает тот приятный факт, что строку можно рассматривать как массив и получать без труда каждый ее символ. Каждый символ строки имеет тип char, доступный только для чтения, но не для записи.
Вот пример, в котором над строками выполняются данные операции:
public void TestOpers()
{
//операции над строками string
s1 ="АВС", s2 ="CDE";
string s3 = s1+s2;
bool b1= (s1==s2);
char ch1 = s1 [0], ch2 = s2[0];
Console.WriteLine("s1={0}, s2={1}, b1={2}," +
"ch1={3}, ch2={4}", s1,s2,b1,chi,ch2);
s2 = s1;
b1 = (s1!=s2);
ch2 = s2 [0];
Console.WriteLine("s1={0}, s2={1}, b1={2}," +
"ch1={3 }, ch2={4 } ", s1,s2,b1,ch1,ch2);
//Неизменяемые значения
s1= "Zenon";
//s1[0]='L';
}
Строковые константы
Без констант не обойтись. В C# существуют два вида строковых констант:
• обычные константы, которые представляют строку символов, заключенную в кавычки;
• @-константы, заданные обычной константой с предшествующим знаком @.
В обычных константах некоторые символы интерпретируются особым образом. Связано это прежде всего с тем, что необходимо уметь задавать в строке непечатаемые символы, такие, как, например, символ табуляции. Возникает необходимость задавать символы их кодом — в виде escape-последовательностей. Для всех этих целей используется комбинация символов, начинающаяся символом "\" — обратная косая черта. Так, пары символов: "\n", "\t", "\\", "\"" задают соответственно символ перехода на новую строку, символ табуляции, сам символ обратной косой черты, символ кавычки, вставляемый в строку, но не сигнализирующий о ее окончании. Комбинация "\xNNNN" задает символ, определяемый шестнадцатеричным кодом NNNN. Хотя такое решение возникающих проблем совершенно естественно, иногда возникают неудобства: например, при задании констант, определяющих путь к файлу, приходится каждый раз удваивать символ обратной косой черты. Это одна из причин, по которой появились @-константы.
В @-константах все символы трактуются в полном соответствии с их изображением. Поэтому путь к файлу лучше задавать @-константой. Единственная проблема в таких случаях: как задать символ кавычки, чтобы он не воспринимался как конец самой константы. Решением является удвоение символа. Вот соответствующие примеры:
//Два вида констант
s1= "\х50";
s2 = @"\х50""";
b1 (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1 = "c: \\c#book\\ch5\\chapter5.doc";
s2 = @"c: \c#book\ch5\chapter5.doc";
b1= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
s1= "\" A\"";
s2=@"""A""";
bl= (s1==s2);
Console.WriteLine("s1={0}, s2={1}, b1={2}", s1,s2,b1);
Взгляните на результаты работы приведенных фрагментов кода, полученные при вызове процедур TestDeclStrings и TestOpers.
Рис. 14.1. Объявления, константы и операции над объектами string
Неизменяемый класс String
В языке C# существует понятие неизменяемый (immutable) класс. Для такого класса невозможно изменить значение объекта при вызове его методов. Динамические методы могут создавать новый объект, но не могут изменить значение существующего объекта.
К таким неизменяемым классам относится и класс String. Ни один из методов этого класса не меняет значения существующих объектов. Конечно, некоторые из методов создают новые значения и возвращают в качестве результата новые строки. Невозможность изменять значения строк касается не только методов. Аналогично, при работе со строкой как с массивом разрешено только чтение отдельных символов, но не их замена. Оператор присваивания из нашего последнего примера, в котором делается попытка изменить первый символ строки, недопустим, а потому закомментирован.
//Неизменяемые значения
s1= "Zenon"; ch1 = s1 [0];
//s1[0]='L';
Таблица 14.1. Статические методы и свойства класса String
Статические свойства и методы класса String
Метод ∙ Описание
Empty ∙ Возвращается пустая строка. Свойство со статусом read only
Compare ∙ Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. При этом можно учитывать или не учитывать регистр, особенности национального форматирования дат, чисел и т. д.
CompareOrdinal ∙ Сравнение двух строк. Метод перегружен. Реализации метода позволяют сравнивать как строки, так и подстроки. Сравниваются коды символов
Concat ∙ Конкатенация строк. Метод перегружен, допускает сцепление произвольного числа строк
Copy ∙ Создается копия строки
Format ∙ Выполняет форматирование в соответствии с заданными спецификациями формата. Ниже приведено более полное описание метода
Intern, Islntern ∙ Отыскивается и возвращается ссылка на строку, если таковая уже хранится во внутреннем пуле данных. Если же строки нет, то первый из методов добавляет строку во внутренний пул, второй — возвращает null. Методы применяются обычно тогда, когда строка создается с использованием построителя строк — класса StringBuilder
Join ∙ Конкатенация массива строк в единую строку. При конкатенации между элементами массива вставляются разделители. Операция, заданная методом Join, является обратной к операции, заданной методом Split. Последний является динамическим методом и, используя разделители, осуществляет разделение строки на элементы
Метод Format
Метод Format в наших примерах встречался многократно. Всякий раз, когда выполнялся вывод результатов на консоль, неявно вызывался и метод Format. Рассмотрим оператор печати:
Console.WriteLine("s1={0}, s2={1}", s1,s2);
Здесь строка, задающая первый аргумент метода, помимо обычных символов, содержит форматы, заключенные в фигурные скобки. В данном примере используется простейший вид формата — он определяет объект, который должен быть подставлен в участок строки, занятый данным форматом. Помимо неявных вызовов, нередко возникает необходимость явного форматирования строки.
Давайте рассмотрим общий синтаксис как самого метода Format, так и используемых в нем форматов. Метод Format, как и большинство методов, является перегруженным и может вызываться с разным числом параметров. Первый необязательный параметр метода задает провайдера, определяющего национальные особенности, которые используются в процессе форматирования. В качестве такого параметра должен быть задан объект, реализующий интерфейс System.IFormatProvider. Если этот параметр не задан, то используется культура, заданная по умолчанию. Вот примеры двух реализаций этого метода:
public static string Format(string, object);
public static string Format(IFormatProvider, string, params object[]);