Объявление строк. Конструкторы класса string

Методы и передача параметров

Аналогично полям и свойствам методы определяются только внутри класса, и для них в индивидуальном порядке используется модификатор доступа.

Создадим для примера с автомобилем метод для ускорения автомобиля. Будем передавать в него изменение скорости. Будем контролировать разрешенную максимальную скорость и следить, чтобы скорость не стала отрицательной. И в качестве возвращаемого значения будем возвращать «true» в случае, если скорость изменилась.

public bool SpeedUp(double accValue)

{

double oldValue = CurrentSpeed;

if ((CurrentSpeed + accValue) > MaxCitySpeed)

CurrentSpeed = MaxCitySpeed;

Else

CurrentSpeed = CurrentSpeed + accValue;

if (CurrentSpeed < 0) CurrentSpeed = 0;

return (oldValue != CurrentSpeed);

}

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

public double MakeSumm(double a, double b)

{

return a + b;

}

Если вспомнить С++, то были три возможности передавать параметры по значению, указателю и ссылке.

При передаче по значению происходило создание новой переменной на стеке и следовало побитовое копирование значения.

При передаче по указателю и по ссылке происходила передача адреса переменной. При передаче по ссылке мы работали с объектом «напрямую», а не через указатель.

Теперь в C# адрес объекта скрыт. Поэтому при передаче в качестве параметра переменной структурного типа происходит его копирование по значению, следовательно, на стеке создается новая переменная. При передаче переменной ссылочного типа, происходит создание на стеке новой ссылки. Если поменяем значение структурного типа или присвоим ссылке новое значение, то при выходе из метода ничего не изменится сверху.

Если необходимо вернуть из метода измененный параметр, то в языке С# для этих целей используется два новых ключевых слова out и ref.

Если взглянуть на проблему передачи параметров, то параметры методов бывают трех типов: входные [in], исходящие [out] и входящие-исходящие [in-out].

[out] параметры отличаются от [in-out], тем что [out] параметры должны быть обязательно инициализированы внутри тела метода. Т.е. при любом ветвлении тела метода, при выходе из него, [out] параметру должно быть присвоено значение. При передаче [out] параметра в метод его не обязательно инициализировать. Для [in-out] параметра все строго наоборот. Он может не измениться внутри тела метода, но обязан быть инициализирован до его подстановки в метод.

В С# если для параметра не указан тип out или ref, то параметр считается входящим и передается по значению (для ссылок по значению передается ссылка).

Для нашего примера сделаем метод, который должен создать и вернуть ссылку на новый автомобиль и при исполнении некоторого условия увеличить скорость входящего параметра (пока не обращаем внимания на слово static).

public static void SampleMethod( out Car newCar, ref double speed)

{

newCar = new Car();

newCar.CurrentSpeed = speed;

if (speed < Car.MaxCitySpeed / 2) speed += 10;

}

При вызове метода и подстановке параметров, так же необходимо указывать out или ref для соотвествующего параметра.

void Main(string[] args)

{

Пустая ссылка

Car car;

Необходимо инициализировать

double speed = 20;

Вызываем метод

Car.SampleMethod(out car, ref speed);

Выводим новые значения

Console.WriteLine("Car speed: {0} New speed: {1}", car.CurrentSpeed, speed);

Console.ReadLine();

}

Еще раз как итог… Использование модификатора refприводит к созданию вызова по ссылке, а не по значению. Модификатор refуказывается при объявлении метода и при его вызове.

Иногда параметр ссылочного типа используется для получения значения из метода, а не для передачи ему значения. Метод может выполнять некоторую функцию (например, открытие сетевого соединения) и возвращать в параметре ссылочного типа какое-либо значение, определенное для указания успешного или неудачного выполнения операции. Для этой цели в C# предусмотрен модификатор out. При объявлении метода в круглых скобках указывается не информация, которую нужно передать методу, а информация, которая будет получена из метода.

Отличие между модификаторами refи outзаключается в том, что параметр с модификатором out может использоваться только для передачи значения из метода. При этом нет необходимости до вызова метода присваивать переменной начальное значение. Более того, внутри метода параметр с модификатором out всегда рассматривается как не имеющий начального значения. Метод обязан присвоить значение параметру, прежде чем передаст управление вызывающей подпрограмме. То есть, после вызова метода параметр outвсегда будет иметь значение.

Модификаторы доступа:для полей, свойств, методов и событий существует четыре вида модификаторов доступа: public, protected, private и internal.

Для первых трех модификаторов не должно быть никаких вопросов, т.к. все аналогично языку C++. Модификатор internal это модификатор public, но помеченное им поле, свойство или метод будут доступны только внутри сборки.

При подключении dll файла с библиотекой этот метод не будет виден.

Модификатор internal необходимо рассматривать как еще один уровень инкапсуляции данных. Он скрывает определение типов, полей, свойств и методов внутри одной сборки.

Класс String

Основным типом при работе со строками является тип string, задающий строки переменной длины. Класс String в языке C# относится к ссылочным типам. Над строками - объектами этого класса - определен широкий набор операций, соответствующий современному представлению о том, как должен быть устроен строковый тип.

Объявление строк. Конструкторы класса string

Объекты класса string объявляются как все прочие объекты простых типов. Чаще всего инициализация задается строковой константой.

Примеры объявления строк с вызовом разных конструкторов:

public void TestDeclStrings(){ //конструкторы string world = "Мир"; //string s1 = new string("s1"); // нельзя //string s2 = new string(); // нельзя string sssss = new string('s',5); char[] yes = "Yes".ToCharArray(); string stryes = new string(yes); string strye = new string(yes,0,2); Console.WriteLine("world = {0}; sssss={1}; stryes={2};"+" strye= {3}", world, sssss, stryes, strye);}

Объект world создан без явного вызова конструктора, а объекты sssss, stryes, strye созданы разными конструкторами класса String.

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

Операции над строками

Над строками определены следующие операции:

  • присваивание ( = );
  • операции проверки эквивалентности ( == ) и ( != );
  • конкатенация или сцепление строк ( + );
  • взятие индекса ( [] ).

Начнем с присваивания, имеющего важную особенность. Поскольку string - это ссылочный тип, то в результате присваивания создается ссылка на константную строку, хранимую в "куче". С одной и той же строковой константой в "куче" может быть связано несколько переменных строкового типа. Но эти переменные не являются псевдонимами - разными именами одного и того же объекта. Дело в том, что строковые константы в "куче" не изменяются, поэтому, когда одна из переменных получает новое значение, она связывается с новым константным объектом в "куче". Остальные переменные сохраняют свои связи. Для программиста это означает, что семантика присваивания строк аналогична семантике значимого присваивания.

В отличие от других ссылочных типов, операции, проверяющие эквивалентность, сравнивают значения строк, а не ссылки. Эти операции выполняются как над значимыми типами.

Бинарная операция " + " сцепляет две строки, приписывая вторую строку к хвосту первой.

Возможность взятия индекса при работе со строками отражает тот приятный факт, что строку можно рассматривать как массив и получать без труда каждый ее символ. Каждый символ строки имеет тип char, доступный только для чтения, но не для записи.

Вот пример, в котором над строками выполняются данные операции:

public void TestOpers(){ //операции над строками string s1 ="ABC", s2 ="CDE"; string s3 = s1+s2; bool b1 = (s1==s2); char ch1 = s1[0]; char ch2=s2[0]; Console.WriteLine("s1={0}, s2={1}, b1={2}," + "ch1={3}, ch2={4}", s1,s2,b1,ch1,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);}

Методы Join и Split

Методы Join и Split выполняют над строкой текста взаимно обратные преобразования. Динамический метод Split позволяет осуществить разбор текста на элементы. Статический метод Join выполняет обратную операцию, собирая строку из элементов.

Заданный строкой текст зачастую представляет собой совокупность структурированных элементов - абзацев, предложений, слов, скобочных выражений и т.д. При работе с таким текстом необходимо разделить его на элементы, пользуясь специальными разделителями элементов, - это могут быть пробелы, скобки, знаки препинания. Практически подобные задачи возникают постоянно при работе со структурированными текстами. Методы Split и Join облегчают решение этих задач.

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

public string[] Split(params char[]);

На вход методу Split передается один или несколько символов, интерпретируемых как разделители. Объект string, вызвавший метод, разделяется на подстроки, ограниченные этими разделителями. Из этих подстрок создается массив, возвращаемый в качестве результата метода.

Синтаксис статического метода Join таков:

public static string Join(string delimiters, string[] items );

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

Рассмотрим примеры применения этих методов. В первом из них строка представляет сложноподчиненное предложение, которое разбивается на простые предложения. Во втором предложение разделяется на слова. Затем производится обратная сборка разобранного текста. Вот код соответствующей процедуры:

public void TestSplitAndJoin(){ string txt = "А это пшеница, которая в темном чулане хранится," + " в доме, который построил Джек!"; Console.WriteLine("txt={0}", txt); Console.WriteLine("Разделение текста на простые предложения:"); string[] SimpleSentences, Words; //размерность массивов SimpleSentences и Words //устанавливается автоматически в соответствии с //размерностью массива, возвращаемого методом Split SimpleSentences = txt.Split(','); for(int i=0;i< SimpleSentences.Length; i++) Console.WriteLine("SimpleSentences[{0}]= {1}",i, SimpleSentences[i]); string txtjoin = string.Join(",",SimpleSentences); Console.WriteLine("txtjoin={0}", txtjoin); Words = txt.Split(',', ' '); for(int i=0;i< Words.Length; i++) Console.WriteLine("Words[{0}]= {1}",i, Words[i]); txtjoin = string.Join(" ",Words); Console.WriteLine("txtjoin={0}", txtjoin);}

Результаты выполнения этой процедуры показаны на рис.

Объявление строк. Конструкторы класса string - student2.ru

Еще полезные методы класса String

Операции, разрешенные над строками в C#, позволяют выполнять вставку, удаление, замену, поиск вхождения подстроки в строку.

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

Метод Описание
Insert Вставляет подстроку в заданную позицию
Remove Удаляет подстроку в заданной позиции
Replace Заменяет подстроку в заданной позиции на новую подстроку
Substring Выделяет подстроку в заданной позиции
IndexOf, IndexOfAny, LastIndexOf, LastIndexOfAny Определяются индексы первого и последнего вхождения заданной подстроки или любого символа из заданного набора
StartsWith, EndsWith Возвращается true или false, в зависимости от того, начинается или заканчивается строка заданной подстрокой
PadLeft, PadRight Выполняет набивку нужным числом пробелов в начале и в конце строки
Trim, TrimStart, TrimEnd Обратные операции к методам Pad. Удаляются пробелы в начале и в конце строки, или только с одного ее конца
ToCharArray Преобразование строки в массив символов

Наши рекомендации