На этом шаге мы закончим рассмотрение основных операций с текстовыми объектами.
Мы уже знаем, что к текстовым значениям может применяться такая арифметическая операция, как сложение. Если складываются (с помощью оператора + ) два текстовых значения, то создается новый текстовый объект, который содержит текст, получающийся объединением складываемых текстовых значений. Результатом выражения возвращается ссылка на созданный объект.
Если из двух складываемых операндов лишь один является текстовым, то второй автоматически приводится к текстовому формату (если это возможно), и уже после этого текстовые строки объединяются. Но здесь нужно быть очень аккуратными. Как пример рассмотрим следующий фрагмент кода:
String txt = "Четыpe " + 2 + 2;
Вопрос в том, какой текст в итоге присваивается переменной txt. Ответ такой: переменной txt присваивается текст "Четыре 22". Выражение "Четыре "+2+2 вычисляется слева направо. Сначала вычисляется значение выражения "Четыре "+2. В этом выражении один операнд текстовый, а другой целочисленный. Целочисленный операнд приводится к текстовому типу, складываемые текстовые строки объединяются, и в итоге получается строка "Четыре 2". К этому текстовому значению прибавляется целочисленное значение 2, то есть вычисляется значение выражения "Четыре 2"+2. Второй целочисленный операнд приводится к текстовому типу, и в итоге получаем строку "Четыре 22". Результат будет иным, если при определении значения переменной txt воспользоваться следующей командой:
String txt = "Четыpe " + (2 + 2);
В этом случае круглые скобки изменяют порядок выполнения операций: сначала вычисляется значение выражения 2+2 (получаем число 4), а затем полученное значение прибавляется к текстовой строке "Четыре ". В итоге переменной txt присваивается текст "Четыре 4".
Еще одна операция, имеющая важное прикладное значение сравнение текстовых строк на предмет равенства/неравенства. Выполняется сравнение строк с помощью операторов
Значение выражения А!=В равно true в случае, если переменные А и В ссылаются на объекты, содержащие разный текст. Если эти объекты содержат одинаковый текст, то значение выражения А!=В равно false.
А для текстовых объектов (то есть когда А и В являются объектными переменными класса String) при вычислении выражений А==В и А!=В сравниваются не адреса объектов, а сами объекты. То есть для объектов класса String сравнение с помощью операторов == и ! = выполняется по-особому. Отметим, что для сравнения текстовых объектов также может использоваться метод Equals(). Благодаря механизму перегрузки операторов, существующему в С#, для объектов пользовательских классов можно изменить способ сравнения объектов.
Скромная программа, в которой в разных ситуациях используется сравнение текстовых значений, представлена ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr97_1 { class Program { // Статический метод для сравнения текстовых строк: static bool StrCmp(String X, String Y) { // Если строки разной длины: if (X.Length != Y.Length) return false; // Если строки одинаковой длины: for(int k = 0; k < X.Length; k++) { // Если символы в текстовых строках разные: if (X[k] != Y[k]) return false; } // Результат метода, если строки одинаковой длины // и все символы в текстовых строках совпадают: return true; } // Главный метод: static void Main() { // Символьный массив: char[] smb = {'Я', 'з', 'ы', 'к', ' ', 'C', '#'}; // Текстовый объект: String A = "Язык C#"; // Отображение текстовой строки: Console.WriteLine("А: \"{0}\"", A); // Создание нового текстового объекта: String B = new String(smb); // Отображение текстовой строки: Console.WriteLine("В: \"{0}\"", B); // Еще один текстовый объект: String C = "ЯЗЫК C#"; // Отображение текстовой строки: Console.WriteLine("С: \"{0}\"", C); Console.WriteLine("Сравнение строк"); // Сравнение текстовых строк: Console.WriteLine("А==В: {0}", A==B); Console.WriteLine("StrCmp(А, В): {0}", StrCmp(A, B)); Console.WriteLine("А==С: {0}", A==C); Console.WriteLine("StrCmp(А, С): {0}", StrCmp(A, C)); Console.WriteLine("В!=С: {0}", B!=C); Console.WriteLine("StrCmp(А,\"C#\"): {0}", StrCmp(A,"C#")); // Задержка: Console.ReadLine(); } } }
При выполнении программы получаем такой результат.
Рис.1. Результат работы приложения
В этой простой программе с помощью операторов == и ! = сравнивается несколько текстовых строк. Также в программе есть описание статического метола StrCmp(), предназначенного для сравнения текстовых строк. Анализ программы начнем с кода метода StrCmp().
Метод StrCmp() описан как статический в том же классе, что и главный метод программы. Поэтому метод StrCmp() можно вызывать в методе Main() без указания названия класса. У метода StrCmp() два текстовых аргумента (объектные переменные X и Y класса String). Через эти переменные методу передаются текстовые значения для сравнения. Если тексты одинаковые, то метод должен возвращать результатом логическое значение true. Если сравниваемые тексты отличаются, то результатом метода должно быть значение false. При выполнении кода метода сначала сравнивается длина текстовых значений. Понятно, что если два текста имеют разную длину, то совпадать они не могут. Это, так сказать, формальная проверка. Выполняется она с помощью условного оператора (в упрощенной форме), в котором проверяется условие X.Length != Y. Length. Если условие истинно, то инструкцией
return false;
return false;
return true;
В главном методе создается несколько текстовых объектов, которые затем сравниваются (с помощью операторов == и !=, а также метода StrCmp()). Объект А создается присваиванием литерала "Язык С#". Объект В создается на основе предварительно объявленного и инициализированного символьного массива, но в итоге получается объект с таким же текстовым значением, как и объект А. Объект С получает значением текстовый литерал "ЯЗЫК С#". От значений объектов А и В данный текст отличается лишь регистром букв.
Также стоит заметить, что текстовые объекты реализуются по следующей схеме: объектная переменная ссылается на объект, содержащий текст. Поэтому присваивание текстового значения переменной следует понимать в том смысле, что переменная будет ссылаться на объект, содержащий присвоенный текст. Для удобства, если это не приводит к недоразумениям, мы иногда не будем заострять внимание на таких деталях.
Для сравнения текстовых значений используются выражения А==В (равенство текстовых значений в объектах, на которые ссылаются переменные А и В результат равен true), А==С (проверка на предмет совпадения текстовых значений в объектах, на которые ссылаются переменные А и С - результат равен false), В!=С (проверка на предмет неравенства текстовых значений в объектах, на которые ссылаются переменные В и С - результат равен true). Аналогичные проверки выполняются с помощью описанного в программе статического метода StrCmp(). Как несложно заметить, результаты проверок вполне ожидаемые.
Иногда для сравнения текстовых значений без учета состояния регистра можно текстовые значения предварительно перевести в верхний или нижний регистр. Для перевода символов текста в верхний регистр используется метод ToUpper(), а для перевода символов текста в нижний регистр используют метод ToLower() (методы обсуждаются в следующих шагах). Например, чтобы сравнить значения текстовых переменных А и В на предмет равенства без учета состояния регистра, можно использовать выражения A.ToUpper()==В.ToUpper() или A.ToLower()==B.ToLower(). При этом значения переменных А и В не меняются.
На следующем шаге мы рассмотрим методы для работы с текстом.