- •Visual Studio .Net - открытая среда разработки
- •Открытость
- •Framework .Net - единый каркас среды разработки
- •Библиотека классов fcl - статический компонент каркаса
- •Единство каркаса
- •Встроенные примитивные типы
- •Структурные типы
- •Архитектура приложений
- •Модульность
- •Общеязыковая исполнительная среда clr - динамический компонент каркаса
- •Двухэтапная компиляция. Управляемый модуль и управляемый код
- •Виртуальная машина
- •Дизассемблер и ассемблер
- •Метаданные
- •Сборщик мусора - Garbage Collector - и управление памятью
- •Исключительные ситуации
- •События
- •Общие спецификации и совместимые модули
- •Создание c#
- •Виды проектов
- •Консольный проект
- •Windows-проект
- •Начало начал - точка "большого взрыва"
- •Выполнение проекта по умолчанию после "большого взрыва"
- •Проект WindowsHello
- •На этом мы закончим первое знакомство с проектaми на c# и в последующих лекциях приступим к сОбщий взгляд
- •Система типов
- •Типы или классы? и типы, и классы
- •Семантика присваивания
- •Преобразование к типу object
- •Примеры преобразований
- •Семантика присваивания. Преобразования между ссылочными и значимыми типами
- •Операции "упаковать" и "распаковать" (boxing и unboxing).
- •Где, как и когда выполняются преобразования типов?
- •Преобразования ссылочных типов
- •Преобразования типов в выражениях
- •Преобразования внутри арифметического типа
- •Явные преобразования
- •Преобразования строкового типа
- •Преобразования и класс Convert
- •Проверяемые преобразования
- •Исключения и охраняемые блоки. Первое знакомство
- •Опасные вычисления в охраняемых проверяемых блоках
- •Опасные вычисления в охраняемых непроверяемых блоках
- •Опасные преобразования и методы класса Convert
- •Объявление переменных
- •Проект Variables
- •Синтаксис объявления
- •Время жизни и область видимости переменных
- •Глобальные переменные уровня модуля. Существуют ли они в c#?
- •Локальные переменные
- •Глобальные переменные уровня процедуры. Существуют ли?
- •Константы
- •Выражения
- •Приоритет и порядок выполнения операций
- •Перегрузка операций
- •С чего начинается выполнение выражения
- •Операции "увеличить" и "уменьшить" (increment, decrement)
- •Операции sizeof и typeof
- •Как получить подробную информацию о классе?
- •Статические поля и методы арифметических классов
- •Операция new
- •Арифметические операции
- •Операции отношения
- •Операции проверки типов
- •Операции сдвига
- •Логические операции
- •Условное выражение
- •Операция приведения к типу
- •В данном примере явное преобразование из типа double в тип int выполняется, а преобразованиПрисваивание
- •Специальные случаи присваивания
- •Определенное присваивание
- •Еще раз о семантике присваивания
- •Рассмотрим объявления:
- •Класс Math и его функции
- •Класс Random и его функции
- •Операторы языка c#
- •Оператор присваивания
- •Блок или составной оператор
- •Пустой оператор
- •Операторы выбора
- •Оператор if
- •Оператор switch
- •Операторы перехода
- •Оператор goto
- •Операторы break и continue
- •Оператор return
- •Операторы цикла
- •Оператор for
- •Циклы While
- •Цикл foreach
- •Процедуры и функции - функциональные модули
- •Процедуры и функции - методы класса
- •Процедуры и функции. Отличия
- •Описание методов (процедур и функций). Синтаксис
- •Список формальных аргументов
- •Тело метода
- •Вызов метода. Синтаксис
- •О соответствии списков формальных и фактических аргументов
- •Вызов метода. Семантика
- •Что нужно знать о методах?
- •Почему у методов мало аргументов?
- •Поля класса или функции без аргументов?
- •Пример: две версии класса Account
- •Функции с побочным эффектом
- •Методы. Перегрузка
- •Корректность методов
- •Инварианты и варианты цикла
- •Рекурсия
- •Рекурсивное решение задачи "Ханойские башни"
- •Быстрая сортировка Хоара
- •Общий взгляд
- •Объявление массивов
- •Объявление одномерных массивов
- •Динамические массивы
- •Многомерные массивы
- •Массивы массивов
- •Процедуры и массивы
- •Класс Array
- •Массивы как коллекции
- •Сортировка и поиск. Статические методы класса Array
- •Сводка свойств и методов класса Array
- •Класс Object и массивы
- •Массивы объектов
- •Массивы. Семантика присваивания
- •Общий взгляд
- •Строки с#
- •Класс char
- •Класс char[] - массив символов
- •Существует ли в c# тип char*
- •Пространство имен RegularExpression и классы регулярных выражений
- •Немного теории
- •Синтаксис регулярных выражений
- •Знакомство с классами пространства RegularExpressions
- •Класс Regex
- •Классы Match и MatchCollection
- •Классы Group и GroupCollection
- •Классы Capture и CaptureCollection
- •Перечисление RegexOptions
- •Класс RegexCompilationInfo
- •Примеры работы с регулярными выражениями
- •Пример "чет и нечет"
- •Пример "око и рококо"
- •Пример "кок и кук"
- •Пример "обратные ссылки"
- •Пример "Дом Джека"
- •Пример "Атрибуты"
- •Классы и ооп
- •Две роли классов
- •Синтаксис класса
- •Поля класса
- •Доступ к полям
- •Методы класса
- •Доступ к методам
- •Методы-свойства
- •Индексаторы
- •Операции
- •Статические поля и методы класса
- •Константы
- •Конструкторы класса
- •Деструкторы класса
- •Проектирование класса Rational
- •Свойства класса Rational
- •Конструкторы класса Rational
- •Методы класса Rational
- •Закрытый метод нод
- •Печать рациональных чисел
- •Тестирование создания рациональных чисел
- •Операции над рациональными числами
- •Константы класса Rational
- •Развернутые и ссылочные типы
- •Классы и структуры
- •Структуры
- •Синтаксис структур
- •Класс Rational или структура Rational
- •Встроенные структуры
- •Еще раз о двух семантиках присваивания
- •Перечисления
- •Персоны и профессии
- •Отношения между классами
- •Отношения "является" и "имеет"
- •Отношение вложенности
- •Расширение определения клиента класса
- •Отношения между клиентами и поставщиками
- •Сам себе клиент
- •Наследование
- •Добавление полей потомком
- •Конструкторы родителей и потомков
- •Добавление методов и изменение методов родителя
- •Статический контроль типов и динамическое связывание
- •Три механизма, обеспечивающие полиморфизм
- •Пример работы с полиморфным семейством классов
- •Абстрактные классы
- •Классы без потомков
- •Интерфейсы
- •Две стратегии реализации интерфейса
- •Преобразование к классу интерфейса
- •Проблемы множественного наследования
- •Коллизия имен
- •Наследование от общего предка
- •Встроенные интерфейсы
- •Упорядоченность объектов и интерфейс iComparable
- •Клонирование и интерфейс iCloneable
- •Сериализация объектов
- •Класс с атрибутом сериализации
- •Интерфейс iSerializable
- •Как определяется функциональный тип и как появляются его экземпляры
- •Функции высших порядков
- •Вычисление интеграла
- •Построение программных систем методом "раскрутки". Функции обратного вызова
- •Наследование и полиморфизм - альтернатива обратному вызову
- •Делегаты как свойства
- •Операции над делегатами. Класс Delegate
- •Пример "Комбинирование делегатов"
- •Пример "Плохая служба"
- •Классы с событиями
- •Класс sender. Как объявляются события?
- •Делегаты и события
- •Как зажигаются события
- •Классы receiver. Как обрабатываются события
- •Классы с событиями, допустимые в каркасе .Net Framework
- •Пример "Списки с событиями"
- •Класс sender
- •Классы receiver
- •Две проблемы с обработчиками событий
- •Игнорирование коллег
- •Переопределение значений аргументов события
- •Классы с большим числом событий
- •Проект "Город и его службы"
- •Наследование и универсальность
- •Синтаксис универсального класса
- •Класс с универсальными методами
- •Два основных механизма объектной технологии
- •Стек. От абстрактного, универсального класса к конкретным версиям
- •Ограниченная универсальность
- •Синтаксис ограничений
- •Список с возможностью поиска элементов по ключу
- •Как справиться с арифметикой
- •Родовое порождение класса. Предложение using
- •Универсальность и специальные случаи классов
- •Универсальные структуры
- •Универсальные интерфейсы
- •Универсальные делегаты
- •Framework .Net и универсальность
- •Корректность и устойчивость программных систем
- •Жизненный цикл программной системы
- •Три закона программотехники Первый закон (закон для разработчика)
- •Второй закон (закон для пользователя)
- •Третий закон (закон чечако)
- •Отладка
- •Создание надежного кода
- •Искусство отладки
- •Отладочная печать и условная компиляция
- •Классы Debug и Trace
- •Метод Флойда и утверждения Assert
- •Классы StackTrace и BooleanSwitch
- •Отладка и инструментальная среда Visual Studio .Net
- •Обработка исключительных ситуаций
- •Выбрасывание исключений. Создание объектов Exception
- •Захват исключения
- •Параллельная работа обработчиков исключений
- •Блок finally
- •Класс Exception
- •Организация интерфейса
- •Форма и элементы управления
- •Взаимодействие форм
- •Модальные и немодальные формы
- •Передача информации между формами
- •Образцы форм
- •Главная кнопочная форма
- •Шаблон формы для работы с классом
- •Работа со списками (еще один шаблон)
- •Элемент управления класса ListBox
- •Наследование форм
- •Два наследника формы TwoLists
- •Огранизация меню в формах
- •Создание меню в режиме проектирования
- •Классы меню
- •Создание инструментальной панели с командными кнопками
- •Рисование в форме
- •Класс Graphics
- •Методы класса Graphics
- •Класс Pen
- •Класс Brush
- •Проект "Паутина Безье, кисти и краски"
- •Паутина Безье
- •Событие Paint
- •Кисти и краски
- •Абстрактный класс Figure
- •Классы семейства геометрических фигур
- •Класс Ellipse
- •Класс Circle
- •Класс LittleCircle
- •Класс Rect
- •Класс Square
- •Класс Person
- •Список с курсором. Динамические структуры данных
- •Классы элементов списка
- •Организация интерфейса
Строки с#
Давайте разберемся, как устроены строки C# и что взято из языка С++.
Класс char
В C# есть символьный класс Char, основанный на классе System.Char и использующий двухбайтную кодировку Unicode представления символов. Для этого типа в языке определены символьные константы - символьные литералы. Константу можно задавать:
-
символом, заключенным в одинарные кавычки;
-
escape-последовательностью, задающей код символа;
-
Unicode-последовательностью, задающей Unicode-код символа.
Вот несколько примеров объявления символьных переменных и работы с ними:
public void TestChar()
{
char ch1='A', ch2 ='\x5A', ch3='\u0058';
char ch = new Char();
int code; string s;
ch = ch1;
//преобразование символьного типа в тип int
code = ch; ch1=(char) (code +1);
//преобразование символьного типа в строку
//s = ch;
s = ch1.ToString()+ch2.ToString()+ch3.ToString();
Console.WriteLine("s= {0}, ch= {1}, code = {2}",
s, ch, code);
}//TestChar
Три символьные переменные инициализированы константами, значения которых заданы тремя разными способами. Переменная ch объявляется в объектном стиле, используя new и вызов конструктора класса. Тип char, как и все типы C#, является классом. Этот класс наследует свойства и методы класса Object и имеет большое число собственных методов.
Существуют ли преобразования между классом char и другими классами? Явные или неявные преобразования между классами char и string отсутствуют, но, благодаря методу ToString, переменные типа char стандартным образом преобразуются в тип string. Как отмечалось в лекции 3, существуют неявные преобразования типа char в целочисленные типы, начиная с типа ushort. Обратные преобразования целочисленных типов в тип char также существуют, но они уже явные.
В результате работы процедуры TestChar строка s, полученная сцеплением трех символов, преобразованных в строки, имеет значение BZX, переменная ch равна A, а ее код - переменная code - 65.
Не раз отмечалось, что семантика присваивания справедлива при вызове методов и замене формальных аргументов на фактические. Приведу две процедуры, выполняющие взаимно-обратные операции - получение по коду символа и получение символа по его коду:
public int SayCode(char sym)
{
return (sym);
}//SayCode
public char SaySym(object code)
{
return ((char)((int)code));
}// SaySym
Как видите, в первой процедуре преобразование к целому типу выполняется неявно. Во второй - преобразование явное. Ради универсальности она слегка усложнена. Формальный параметр имеет тип Object, что позволяет передавать ей в качестве аргумента код, заданный любым целочисленным типом. Платой за это является необходимость выполнять два явных преобразования.
Таблица 13.1. Статические методы и свойства класса Char |
|
Метод |
Описание |
GetNumericValue |
Возвращает численное значение символа, если он является цифрой, и (-1) в противном случае |
GetUnicodeCategory |
Все символы разделены на категории. Метод возвращает Unicode категорию символа. Ниже приведен пример |
IsControl |
Возвращает true, если символ является управляющим |
IsDigit |
Возвращает true, если символ является десятичной цифрой |
IsLetter |
Возвращает true, если символ является буквой |
IsLetterOrDigit |
Возвращает true, если символ является буквой или цифрой |
IsLower |
Возвращает true, если символ задан в нижнем регистре |
IsNumber |
Возвращает true, если символ является числом (десятичной или шестнадцатиричной цифрой) |
IsPunctuation |
Возвращает true, если символ является знаком препинания |
IsSeparator |
Возвращает true, если символ является разделителем |
IsSurrogate |
Некоторые символы Unicode с кодом в интервале [0x1000, 0x10FFF] представляются двумя 16-битными "суррогатными" символами. Метод возвращает true, если символ является суррогатным |
IsUpper |
Возвращает true, если символ задан в верхнем регистре |
IsWhiteSpace |
Возвращает true, если символ является "белым пробелом". К белым пробелам, помимо пробела, относятся и другие символы, например, символ конца строки и символ перевода каретки |
Parse |
Преобразует строку в символ. Естественно, строка должна состоять из одного символа, иначе возникнет ошибка |
ToLower |
Приводит символ к нижнему регистру |
ToUpper |
Приводит символ к верхнему регистру |
MaxValue, MinValue |
Свойства, возвращающие символы с максимальным и минимальным кодом. Возвращаемые символы не имеют видимого образа |
Класс Char, как и все классы в C#, наследует свойства и методы родительского класса Object. Но у него есть и собственные методы и свойства, и их немало. Сводка этих методов приведена в таблице 13.1.
Большинство статических методов перегружены. Они могут применяться как к отдельному символу, так и к строке, для которой указывается номер символа для применения метода. Основную группу составляют методы Is, крайне полезные при разборе строки. Приведу примеры, в которых используются многие из перечисленных методов:
public void TestCharMethods()
{
Console.WriteLine("Статические методы класса char:");
char ch='a', ch1='1', lim =';', chc='\xA';
double d1, d2;
d1=char.GetNumericValue(ch); d2=char.GetNumericValue(ch1);
Console.WriteLine("Метод GetNumericValue:");
Console.WriteLine("sym 'a' - value {0}", d1);
Console.WriteLine("sym '1' - value {0}", d2);
System.Globalization.UnicodeCategory cat1, cat2;
cat1 =char.GetUnicodeCategory(ch1);
cat2 =char.GetUnicodeCategory(lim);
Console.WriteLine("Метод GetUnicodeCategory:");
Console.WriteLine("sym '1' - category {0}", cat1);
Console.WriteLine("sym ';' - category {0}", cat2);
Console.WriteLine("Метод IsControl:");
Console.WriteLine("sym '\xA' - IsControl - {0}",
char.IsControl(chc));
Console.WriteLine("sym ';' - IsControl - {0}",
char.IsControl(lim));
Console.WriteLine("Метод IsSeparator:");
Console.WriteLine("sym ' ' - IsSeparator - {0}",
char.IsSeparator(' '));
Console.WriteLine("sym ';' - IsSeparator - {0}",
char.IsSeparator(lim));
Console.WriteLine("Метод IsSurrogate:");
Console.WriteLine("sym '\u10FF' - IsSurrogate - {0}",
char.IsSurrogate('\u10FF'));
Console.WriteLine("sym '\\' - IsSurrogate - {0}",
char.IsSurrogate('\\'));
string str = "\U00010F00";
//Символы Unicode в интервале [0x10000,0x10FFF]
//представляются двумя 16-битными суррогатными символами
Console.WriteLine("str = {0}, str[0] = {1}", str, str[0]);
Console.WriteLine("str[0] IsSurrogate - {0}",
char.IsSurrogate(str, 0));
Console.WriteLine("Метод IsWhiteSpace:");
str ="пробелы, пробелы!" + "\xD" + "\xA" + "Всюду пробелы!";
Console.WriteLine("sym '\xD ' - IsWhiteSpace - {0}",
char.IsWhiteSpace('\xD'));
Console.WriteLine("str: {0}", str);
Console.WriteLine("и ее пробелы - символ 8 {0},символ 17 {1}",
char.IsWhiteSpace(str,8), char.IsWhiteSpace(str,17));
Console.WriteLine("Метод Parse:");
str="A";
ch = char.Parse(str);
Console.WriteLine("str:{0} char: {1}",str, ch);
Console.WriteLine("Минимальное и максимальное значение:{0}, {1}",
char.MinValue.ToString(), char.MaxValue.ToString());
Console.WriteLine("Их коды: {0}, {1}",
SayCode(char.MinValue), SayCode(char.MaxValue));
}//TestCharMethods
Результаты консольного вывода, порожденного выполнением метода, изображены на рис. 13.1.
Рис. 13.1. Вызовы статических методов класса char
Кроме статических методов, у класса Char есть и динамические. Большинство из них - это методы родительского класса Object, унаследованные и переопределенные в классе Char. Из собственных динамических методов стоит отметить метод CompareTo, позволяющий проводить сравнение символов. Он отличается от метода Equal тем, что для несовпадающих символов выдает "расстояние" между символами в соответствии с их упорядоченностью в кодировке Unicode. Приведу пример:
public void testCompareChars()
{
char ch1, ch2;
int dif;
Console.WriteLine("Метод CompareTo");
ch1='A'; ch2= 'Z';
dif = ch1.CompareTo(ch2);
Console.WriteLine("Расстояние между символами {0},
{1} = {2}", ch1, ch2, dif);
ch1='а'; ch2= 'А';
dif = ch1.CompareTo(ch2);
Console.WriteLine("Расстояние между символами {0},
{1} = {2}", ch1, ch2, dif);
ch1='Я'; ch2= 'А';
dif = ch1.CompareTo(ch2);
Console.WriteLine("Расстояние между символами {0},
{1} = {2}", ch1, ch2, dif);
ch1='A'; ch2= 'A';
dif = ch1.CompareTo(ch2);
Console.WriteLine("Расстояние между символами {0},
{1} = {2}", ch1, ch2, dif);
ch1='А'; ch2= 'A';
dif = ch1.CompareTo(ch2);
Console.WriteLine("Расстояние между символами {0},
{1} = {2}", ch1, ch2, dif);
ch1='Ё'; ch2= 'А';
dif = ch1.CompareTo(ch2);
Console.WriteLine("Расстояние между символами {0},
{1} = {2}", ch1, ch2, dif);
}//TestCompareChars
Результаты сравнения изображены на рис. 13.2.
Рис. 13.2. Сравнение символов
Анализируя эти результаты, можно понять, что в кодировке Unicode как латиница, так и кириллица плотно упакованы. Исключение составляет буква Ё - заглавная и малая - они выпадают из плотной кодировки. Малые буквы в кодировке непосредственно следуют за заглавными буквами. Расстояние между алфавитами в кодировке довольно большое - русская буква А на 975 символов правее в кодировке, чем соответствующая буква в латинском алфавите.