Строки и классы
Класс String
Создание строк
Строка как набор символов
Перебор строк
Сравнение строк
Объединение строк. Метод Concat
Объединение строк. Метод Join
Сравнение строк
Поиск в строке. Метод IndexOf
Поиск в строке. Метод LastIndexOf
Поиск в строке. Методы StartsWith и EndsWith
Разделение строк. Метод Split
Разделение строк. Метод Split
Обрезка строки. Метод Trim
Обрезка строки. Метод Substring
Вставка
Удаление строк. Метод Remove
Замена. Метод Replace
Смена регистра
Класс StringBuilder
Вывод StringBuilderв консоль
Длина и емкость StringBuilder
Операции со строками StringBuilder
Операции со строками StringBuilder
Когда надо использовать класс String, а когда StringBuilder?
Классы и объекты
Поля и методы класса
Поля и методы класса
Пример использования методов класса
Модификаторы доступа
Модификаторы доступа
Модификаторы доступа
Модификатор доступа
Создание объекта класса
Обращение к функциональности класса
Обращение к функциональности класса
Создание конструкторов
Создание конструкторов
Создание конструкторов
Создание конструкторов
Ключевое слово this
Цепочка вызова конструкторов
Свойства класса
Свойства класса
Пример описания свойств
Пример описания свойств
Важная информация
Важная информация
584.56K
Category: programmingprogramming

Лекция 11. Строки и классы

1. Строки и классы

СТРОКИ И КЛАССЫ
Ульяновский государственный технический университет

2. Класс String


В языке C# строковые значения представляет тип string, а вся
функциональность
работы
с
данным
типом
сосредоточена
в
классе System.String. Собственно, string является псевдонимом для
класса
String.
Объекты
этого
класса
представляют
текст
как
последовательность символов Unicode. Максимальный размер объекта
String может составлять в памяти 2 ГБ, или около 1 миллиарда
символов.

3. Создание строк

• Создавать строки можно, как используя переменную типа string и
присваивая ей значение, так и применяя один из конструкторов класса
String.
string s1 = "hello";
string s2 = new String('a', 6); // результатом будет строка "aaaaaa"
string s3 = new String(new char[] { 'w', 'o', 'r', 'l', 'd' });
string s4 = new String(new char[] { 'w', 'o', 'r', 'l', 'd' }, 1, 3); // orl
Console.WriteLine(s1);
// hello
Console.WriteLine(s2);
// aaaaaaa
Console.WriteLine(s3);
// world
Console.WriteLine(s4);
// orl

4. Строка как набор символов

• Так как строка хранит коллекцию символов, в ней определен
индексатор для доступа к этим символам. Применяя индексатор, мы
можем обратиться к строке как к массиву символов и получить по
индексу любой из ее символов:
string message = "hello";
// получаем символ
char firstChar = message[1]; // символ 'e'
Console.WriteLine(firstChar);
//e
Console.WriteLine(message.Length);
// длина строки

5. Перебор строк

• Строку можно перебрать в цикле foreach как набор объектов char. Также
можно с помощью других типов циклов перебрать строку, применяя
обращение к символам по индексу:
string message = "hello";
for (var i = 0; i < message.Length; i++)
{
Console.WriteLine(message[i]);
}
foreach (var ch in message)
{
Console.WriteLine(ch);
}

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

• В отличие от других классов строки сравниваются по значению их
символов, а не по ссылкам:
string message1 = "hello";
string message2 = "hello";
Console.WriteLine(message1 == message2);
// true

7. Объединение строк. Метод Concat

• Конкатенация строк или объединение может производиться как с
помощью операции +, так и с помощью метода Concat.
Метод Concat является статическим методом класса string,
принимающим в качестве параметров две строки. Также имеются
другие версии метода, принимающие другое количество параметров.
string s1 = "hello";
string s2 = "world";
string s3 = s1 + " " + s2; // результат: строка "hello world"
string s4 = string.Concat(s3, "!!!"); // результат: строка "hello world!!!"

8. Объединение строк. Метод Join

• Для объединения строк также может использоваться метод Join. Метод
Join также является статическим. Использованная ниже версия метода
получает два параметра: строку-разделитель (в данном случае пробел) и
массив строк, которые будут соединяться и разделяться разделителем.
string s5 = "apple";
string s6 = "a day";
string s7 = "keeps";
string s8 = "a doctor";
string s9 = "away";
string[] values = new string[] { s5, s6, s7, s8, s9 };
string s10 = string.Join(" ", values);
Console.WriteLine(s10); // apple a day keeps a doctor away

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

string s1 = "hello";
Сравнение строк
• Для сравнения строк применяется
статический метод Compare.
Данная версия метода Compare
принимает две строки и
возвращает число. Если первая
строка по алфавиту стоит выше
второй, то возвращается число
меньше нуля. В противном случае
возвращается число больше нуля.
И третий случай - если строки
равны, то возвращается число 0. В
данном случае так как символ h по
алфавиту стоит выше символа w,
то и первая строка будет стоять
выше.
string s2 = "world";
int result = string.Compare(s1, s2);
if (result < 0)
{
Console.WriteLine("Строка s1 перед строкой
s2");
}
else if (result > 0)
{
Console.WriteLine("Строка s1 стоит после
строки s2");
}
else
{
Console.WriteLine("Строки s1 и s2 идентичны");
}
// результатом будет "Строка s1 перед строкой s2"

10. Поиск в строке. Метод IndexOf

• С помощью метода IndexOf мы можем определить индекс первого
вхождения отдельного символа или подстроки в строке:
string s1 = "hello world";
char ch = 'o';
int indexOfChar = s1.IndexOf(ch); // равно 4
Console.WriteLine(indexOfChar);
string substring = "wor";
int indexOfSubstring = s1.IndexOf(substring); // равно 6
Console.WriteLine(indexOfSubstring);

11. Поиск в строке. Метод LastIndexOf

• Подобным образом действует метод LastIndexOf, только находит
индекс последнего вхождения символа или подстроки в строку.
string s1 = "hello world";
char ch = 'o';
int lastIndexOfChar = s1.LastIndexOf(ch); // равно 7
Console.WriteLine(lastIndexOfChar);

12. Поиск в строке. Методы StartsWith и EndsWith

• Еще одна группа методов
позволяет узнать начинается
или заканчивается ли строка на
определенную подстроку. Для
этого предназначены
методы StartsWith и EndsWith
. Например, в массиве строк
хранится список файлов, и нам
надо вывести все файлы с
расширением exe:
string[] files = { "myapp.exe",
"forest.jpg",
"main.exe",
"book.pdf",
"river.png"
};
for (int i = 0; i < files.Length; i++)
{
if (files[i].EndsWith(".exe"))
Console.WriteLine(files[i]);
}

13. Разделение строк. Метод Split

• С помощью функции Split мы можем разделить строку на массив
подстрок. В качестве параметра функция Split принимает массив
символов или строк, которые и будут служить разделителями.
Например, подсчитаем количество слов в сроке, разделив ее по
пробельным символам:
string text = "И поэтому все так произошло";
string[] words = text.Split(' ');
foreach (string s in words)
{
Console.WriteLine(s);
}

14. Разделение строк. Метод Split

• Это не лучший способ разделения по пробелам, так как во входной
строке у нас могло бы быть несколько подряд идущих пробелов и в
итоговый массив также бы попадали пробелы, поэтому лучше
использовать другую версию метода:
string[] words = text.Split(' ', StringSplitOptions.RemoveEmptyEntries);
• Второй параметр StringSplitOptions.RemoveEmptyEntries говорит о том,
что надо удалить все пустые подстроки.

15. Обрезка строки. Метод Trim


Для обрезки начальных или концевых символов используется
функция Trim:
string text = " hello world ";
text = text.Trim(); // результат "hello world"
text = text.Trim(new char[] { 'd', 'h' }); // результат "ello worl"
• Функция Trim без параметров обрезает начальные и конечные пробелы
и возвращает обрезанную строку. Чтобы явным образом указать, какие
начальные и конечные символы следует обрезать, мы можем передать в
функцию массив этих символов.

16. Обрезка строки. Метод Substring

• Обрезать определенную часть
строки позволяет
функция Substring:
• Функция Substring также
возвращает обрезанную строку. В
качестве параметра первая
использованная версия применяет
индекс, начиная с которого надо
обрезать строку. Вторая версия
применяет два параметра - индекс
начала обрезки и длину
вырезаемой части строки.
string text = "Хороший день";
// обрезаем начиная с третьего символа
text = text.Substring(2);
// результат "роший день"
Console.WriteLine(text);
// обрезаем сначала до последних двух
символов
text = text.Substring(0, text.Length 2);
// результат "роший де"
Console.WriteLine(text);

17. Вставка

• Для вставки одной строки в другую применяется функция Insert:
string text = "Хороший день";
string substring = "замечательный ";
text = text.Insert(8, substring);
Console.WriteLine(text);
//
Хороший
замечательный
день
• Первым параметром в функции Insert является индекс, по которому
надо вставлять подстроку, а второй параметр - собственно подстрока.

18. Удаление строк. Метод Remove

• Удалить часть строки
помогает метод Remove:
• Первая версия метода Remove
принимает индекс в строке,
начиная с которого надо
удалить все символы. Вторая
версия принимает еще один
параметр - сколько символов
надо удалить.
string text = "Хороший день";
// индекс последнего символа
int ind = text.Length - 1;
// вырезаем последний символ
text = text.Remove(ind);
Console.WriteLine(text);
ден
// Хороший
// вырезаем первые два символа
text = text.Remove(0, 2);
Console.WriteLine(text);
// роший ден

19. Замена. Метод Replace

• Чтобы заменить один символ или
подстроку на другую,
применяется метод Replace:
• Во втором случае применения
функции Replace строка из
одного символа "о" заменяется на
пустую строку, то есть
фактически удаляется из текста.
Подобным способом легко
удалять какой-то определенный
текст в строках.
string text = "хороший день";
text = text.Replace("хороший", "плохой");
Console.WriteLine(text);
// плохой день
text = text.Replace("о", "");
Console.WriteLine(text);
// плхй день

20. Смена регистра

• Для приведения строки к верхнему и нижнему регистру используются
соответственно функции ToUpper() и ToLower():
string hello = "Hello world!";
Console.WriteLine(hello.ToLower()); // hello world!
Console.WriteLine(hello.ToUpper()); // HELLO WORLD!

21. Класс StringBuilder

• Для создания объекта StringBuilder можно использовать ряд его
конструкторов. Прежде всего можно создать пустой StringBuilder:
using System.Text;
StringBuilder sb = new StringBuilder();
• Можно сразу инициализировать объект определенной строкой:
StringBuilder sb = new StringBuilder("Привет мир");

22. Вывод StringBuilderв консоль


С помощью метода ToString() мы можем получить строку, которая
хранится в StringBuilder:
var sb = new StringBuilder("Hello World");
Console.WriteLine(sb.ToString());
//
Hello World
• Либо можно просто передать объект StringBuilder:
var sb = new StringBuilder("Hello World");
Console.WriteLine(sb);
//
Hello World

23. Длина и емкость StringBuilder

• Для хранения длины строки в классе StringBuilder определенно
свойство Length. Однако есть и вторая величина – емкость выделенной
памяти. Это значение хранится в свойстве Capacity. Емкость — это
выделенная память под объект. Установка емкости позволяет
уменьшить выделения памяти и тем самым повысить
производительность.
• Пример:
StringBuilder sb = new StringBuilder("Привет мир");
Console.WriteLine($"Длина: {sb.Length}");
// Длина: 10
Console.WriteLine($"Емкость: {sb.Capacity}");
// Емкость: 16

24. Операции со строками StringBuilder

Для операций над строками класс StringBuilder определяет ряд методов:
Append: добавляет подстроку в объект StringBuilder
Insert: вставляет подстроку в объект StringBuilder, начиная с определенного индекса
Remove: удаляет определенное количество символов, начиная с определенного индекса
Replace: заменяет все вхождения определенного символа или подстроки на другой символ
или подстроку
• AppendFormat: добавляет подстроку в конец объекта StringBuilder

25. Операции со строками StringBuilder

var sb = new StringBuilder("Привет мир");
sb.Append("!");
sb.Insert(7, "компьютерный ");
Console.WriteLine(sb);
// Привет компьютерный мир!
// заменяем слово
sb.Replace("мир", "world");
Console.WriteLine(sb);
// Привет компьютерный world!
// удаляем 13 символов, начиная с 7-го
sb.Remove(7, 13);
Console.WriteLine(sb);
// Привет world!
// получаем строку из объекта StringBuilder
string text = sb.ToString();
Console.WriteLine(text);
// Привет world!

26. Когда надо использовать класс String, а когда StringBuilder?

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

27. Классы и объекты

• Класс определяется с помощью ключевого слова сlass:
class название_класса
{
// содержимое класса
}
• После слова class идет имя класса и далее в фигурных скобках идет
собственно содержимое класса.
• Пример определения класса Person:
class Person
{
}

28. Поля и методы класса


Класс может хранить некоторые данные. Для хранения данных в
классе применяются поля. По сути поля класса — это переменные,
определенные на уровне класса.
Кроме того, класс может определять некоторое поведение или
выполняемые
действия.
применяются методы.
Для
определения
поведения
в
классе

29. Поля и методы класса


Итак, добавим в класс Person поля и методы:
class Person
{
public string name = "Undefined";
// имя
public int age;
// возраст
public void Print()
{
Console.WriteLine($"Имя: {name}
}
}
Возраст: {age}");

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

class Rectangle
internal class Program
{
{
public int x = 10;
public static void Main(string[] args)
public int y = 20;
{
public int getPerimeter()
Rectangle rect = new Rectangle();
{
int perimeter = rect.getArea();
return 2 * (x + y);
}
public int getArea()
int area = rect.getPerimeter();
Console.WriteLine($"Площадь: {area},
Периметр: {perimeter}");
}
{
return x * y;
}
}
}

31. Модификаторы доступа


Все
поля,
методы
и
остальные
компоненты
класса
имеют модификаторы доступа. Модификаторы доступа позволяют
задать допустимую область видимости для компонентов класса. То есть
модификаторы доступа определяют контекст, в котором можно
употреблять данную переменную или метод.

32. Модификаторы доступа

В языке C# применяются следующие модификаторы доступа:
private: закрытый или приватный компонент класса или структуры. Приватный компонент доступен только в
рамках своего класса или структуры.
private protected: компонент класса доступен из любого места в своем классе или в производных классах,
которые определены в той же сборке.
file: добавлен в версии C# 11 и применяется к типам, например, классам и структурам. Класс или структура с
такими модификатором доступны только из текущего файла кода.
protected: такой компонент класса доступен из любого места в своем классе или в производных классах. При
этом производные классы могут располагаться в других сборках.
internal: компоненты класса или структуры доступен из любого места кода в той же сборке, однако он
недоступен для других программ и сборок.
protected internal: совмещает функционал двух модификаторов protected и internal. Такой компонент класса
доступен из любого места в текущей сборке и из производных классов, которые могут располагаться в других
сборках.
public: публичный, общедоступный компонент класса или структуры. Такой компонент доступен из любого
места в коде, а также из других программ и сборок.

33. Модификаторы доступа

Расположение
вызывающего объекта
public
Protected
internal
protected
internal
Private
protected
private
file
В файле
+
+
+
+
+
+
+
В классе
+
+
+
+
+
+

Произвольный класс (та
же сборка)
+
+
+
+
+


Непроизвольный класс
(другая сборка)
+
+

+



Произвольный класс
(другая сборка)
+
+
+




Непроизводный класс
(другая сборка)
+






34. Модификатор доступа


Мы можем явно задать модификатор
public class Person
{
доступа, а можем его и не указывать:
string name;
Классы,
которые
объявлены
без
public Person(string name)
{
модификатора и которые расположены вне
других
типов,
по
умолчанию
имеют
доступ internal, а вложенные классы, как и
остальные
компоненты
модификатор private.
классов
this.name = name;
имеют
}
public void Print() =>
Console.WriteLine($"Name: {name}");
}

35. Создание объекта класса


После определения класса мы можем создавать его объекты. Для создания объекта
применяются конструкторы. По сути, конструкторы представляют специальные
методы, которые называются так же, как и класс, и которые вызываются при создании
нового объекта класса и выполняют инициализацию объекта. Общий синтаксис
вызова конструктора:
new конструктор_класса(параметры_конструктора);
Сначала идет оператор new, который выделяет память для объекта, а после него
идет вызов конструктора.

36. Обращение к функциональности класса

• Для обращения к функциональности класса – полям, методам (а также
другим элементам класса) применяется точечная нотация точки – после
объекта класса ставится точка, а затем элемент класса:
объект.поле_класса
объект.метод_класса(параметры_метода)

37. Обращение к функциональности класса

internal class Program
// определение класса Person
{
class Person
public static void Main(string[] args)
{
{
public string name = "Undefined";
Person tom = new Person();
класса Person
// создание объекта
public int age;
// Получаем значение полей в переменные
string personName = tom.name;
public void Print()
int personAge = tom.age;
{
Console.WriteLine($"Имя: {personName} Возраст
{personAge}");
// Имя: Undefined Возраст: 0
Console.WriteLine($"Имя: {name}
{age}");
// устанавливаем новые значения полей
}
tom.name = "Tom";
}
tom.age = 37;
// обращаемся к методу Print
tom.Print();
}
}
// Имя: Tom
Возраст: 37
Возраст:

38. Создание конструкторов

// определение класса Person
internal class Program
class Person
{
{
public static void Main(string[] args)
public string name;
{
public int age;
Person tom = new Person();
Создание объекта класса Person
tom.Print();
Возраст: 37
//
public Person()
{
// Имя: Tom
Console.WriteLine("Создание объекта Person");
name = "Tom";
}
age = 37;
}
}
public void Print()
{
Console.WriteLine($"Имя: {name}
}
}
Возраст: {age}");

39. Создание конструкторов

// определение класса Person
class Person
{
public string name;
public int age;
public Person() { name = "Неизвестно"; age = 18; }
// 1 конструктор
public Person(string n) { name = n; age = 18; }
// 2 конструктор
public Person(string n, int a) { name = n; age = a; }
// 3 конструктор
public void Print()
{
Console.WriteLine($"Имя: {name}
}
}
Возраст: {age}");

40. Создание конструкторов

internal class Program
{
public static void Main(string[] args)
{
Person tom = new Person();
// вызов 1-ого конструктора без параметров
Person bob = new Person("Bob");
//вызов 2-ого конструктора с одним параметром
Person sam = new Person("Sam", 25); // вызов 3-его конструктора с двумя параметрами
}
}
tom.Print();
// Имя: Неизвестно
Возраст: 18
bob.Print();
// Имя: Bob
Возраст: 18
sam.Print();
// Имя: Sam
Возраст: 25

41. Создание конструкторов

• Стоит отметить, что начиная с версии C# 9 мы можем сократить вызов
конструктора, убрав из него название типа:
Person tom = new();
// аналогично new Person();
Person bob = new("Bob");
// аналогично new Person("Bob");
Person sam = new("Sam", 25);
// аналогично new Person("Sam", 25);

42. Ключевое слово this

• Ключевое слово this представляет
ссылку на текущий экземпляр/объект
класса.
class Person
{
public string name;
• Оно может использоваться, если
public int age;
название поля класс и параметра
конструктора совпадают:
• this.name
public Person(string name, int age)
{
this.name = name;
= name;
this.age = age;
• первая часть - this.name означает,
что name — это поле текущего класса, а
не название параметра name.
}
}

43. Цепочка вызова конструкторов

• Мы можем обращаться из
одного конструктора к
другому также через ключевое
слово this, передавая нужные
значения для параметров:
• В данном случае первый
конструктор вызывает второй,
а второй конструктор
вызывает третий. По
количеству и типу параметров
компилятор узнает, какой
именно конструктор
вызывается.
class Person
{
public string name;
public int age;
public Person() : this("Неизвестно")
первый конструктор
//
{ }
public Person(string name) : this(name, 18) //
второй конструктор
{ }
public Person(string name, int age)
третий конструктор
{
this.name = name;
this.age = age;
}
}
//

44. Свойства класса

• Свойства служат для организации доступа к полям класса. Как
правило, свойство связано с закрытым полем класса и определяет
методы его получения и установки. Синтаксис свойства:
[модификаторы]
тип_свойства название_свойства
{
get { действия, выполняемые при получении значения свойства}
set { действия, выполняемые при установке значения свойства}
}

45. Свойства класса

• В блоке get выполняются действия по получению значения свойства. В этом
блоке с помощью оператора return возвращаем некоторое значение.
• В блоке set устанавливается значение свойства. В этом блоке с помощью
параметра value мы можем получить значение, которое передано свойству.
• Блоки get и set еще называются акссесорами или методами доступа (к
значению свойства), а также геттером и сеттером.

46. Пример описания свойств

internal class Program
{
public static void Main(string[] args)
{
class Person
Person person = new Person();
{
private string name = "Undefined";
// Устанавливаем свойство - срабатывает блок Set
// значение "Tom" и есть передаваемое в свойство value
public string Name
person.Name = "Tom";
{
get { return name; }
// Получаем значение свойства и присваиваем его
переменной - срабатывает блок Get
set { name = value; }
}
string personName = person.Name;
Console.WriteLine(personName);
}
}
// Tom
}

47. Пример описания свойств

class Person
{
int age = 1;
• Свойства
позволяют
public int Age
вложить
{
set
дополнительную логику, которая
может
быть
установке
необходима
или
{
при
if (value < 1 || value > 120)
получении
Console.WriteLine("Возраст
должен быть в диапазоне от 1 до 120");
else
значения.
age = value;
}
get { return age; }
}
}

48. Важная информация

• Экзамен по дисциплине «Разработка кода информационных систем»
переносится на следующий семестр.
• Но все равно будет проведена промежуточная аттестация по сданным
лабораторным работам следующим образом:
• Каждая лабораторная работа – 1 балл.
• В лабораторных, где есть часть 1 и часть 2 каждая сданная
часть – 0,5 балла.
• Каждая посещенная в этом семестре лекция – 0,2 балла.
• Максимальное количество баллов, которые можно получить
– 12 баллов.

49. Важная информация

• Удовлетворительно – от 60% от максимального
количества баллов = 12 * 60% = 7,2 балла
• Хорошо – от 80% от максимального количества
баллов = 12 * 80% = 9,6 баллов.
• Отлично – от 95% от максимального количества
баллов = 12 * 95% = 11,4 балла.
English     Русский Rules