Similar presentations:
Лекция 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 Rectangleinternal 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. Создание конструкторов
// определение класса Personinternal 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. Создание конструкторов
// определение класса Personclass 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 балла.
programming