- •1. Лекция: Visual Studio .Net, Framework .Net
- •Visual Studio .Net - открытая среда разработки
- •Открытость
- •Framework .Net - единый каркас среды разработки
- •Библиотека классов FCL - статический компонент каркаса
- •Единство каркаса
- •Встроенные примитивные типы
- •Структурные типы
- •Архитектура приложений
- •Модульность
- •Общеязыковая исполнительная среда CLR - динамический компонент каркаса
- •Двухэтапная компиляция. Управляемый модуль и управляемый код
- •Виртуальная машина
- •Дизассемблер и ассемблер
- •Метаданные
- •Сборщик мусора - Garbage Collector - и управление памятью
- •Исключительные ситуации
- •События
- •Общие спецификации и совместимые модули
- •2. Лекция: Язык C# и первые проекты
- •Создание C#
- •Виды проектов
- •Консольный проект
- •Windows-проект
- •Начало начал - точка "большого взрыва"
- •Выполнение проекта по умолчанию после "большого взрыва"
- •Проект WindowsHello
- •3. Лекция: Система типов языка С#
- •Общий взгляд
- •Система типов
- •Типы или классы? И типы, и классы
- •Семантика присваивания
- •Преобразование к типу object
- •Примеры преобразований
- •Семантика присваивания. Преобразования между ссылочными и значимыми типами
- •Операции "упаковать" и "распаковать" (boxing и unboxing).
- •4. Лекция: Преобразования типов
- •Где, как и когда выполняются преобразования типов?
- •Преобразования ссылочных типов
- •Преобразования типов в выражениях
- •Преобразования внутри арифметического типа
- •Явные преобразования
- •Преобразования строкового типа
- •Преобразования и класс Convert
- •Проверяемые преобразования
- •Исключения и охраняемые блоки. Первое знакомство
- •Опасные вычисления в охраняемых проверяемых блоках
- •Опасные вычисления в охраняемых непроверяемых блоках
- •Опасные преобразования и методы класса Convert
- •5. Лекция: Переменные и выражения
- •Объявление переменных
- •Проект Variables
- •Синтаксис объявления
- •Время жизни и область видимости переменных
- •Поля
- •Локальные переменные
- •Глобальные переменные уровня процедуры. Существуют ли?
- •Константы
- •6. Лекция: Выражения. Операции в выражениях
- •Выражения
- •Приоритет и порядок выполнения операций
- •Перегрузка операций
- •С чего начинается выполнение выражения
- •Операции "увеличить" и "уменьшить" (increment, decrement)
- •Операции sizeof и typeof
- •Как получить подробную информацию о классе?
- •Статические поля и методы арифметических классов
- •Операция new
- •Арифметические операции
- •Операции отношения
- •Операции проверки типов
- •Операции сдвига
- •Логические операции
- •Условное выражение
- •Операция приведения к типу
- •7. Лекция: Присваивание и встроенные функции
- •Присваивание
- •Специальные случаи присваивания
- •Определенное присваивание
- •Еще раз о семантике присваивания
- •Рассмотрим объявления:
- •Класс Math и его функции
- •Класс Random и его функции
- •8. Лекция: Операторы языка C#
- •Операторы языка C#
- •Оператор присваивания
- •Блок или составной оператор
- •Пустой оператор
- •Операторы выбора
- •Оператор if
- •Оператор switch
- •Операторы перехода
- •Оператор goto
- •Операторы break и continue
- •Оператор return
- •Операторы цикла
- •Оператор for
- •Циклы While
- •Цикл foreach
- •9. Лекция: Процедуры и функции - методы класса
- •Процедуры и функции - функциональные модули
- •Процедуры и функции - методы класса
- •Процедуры и функции. Отличия
- •Описание методов (процедур и функций). Синтаксис
- •Список формальных аргументов
- •Тело метода
- •Вызов метода. Синтаксис
- •О соответствии списков формальных и фактических аргументов
- •Вызов метода. Семантика
- •Что нужно знать о методах?
- •Почему у методов мало аргументов?
- •Поля класса или функции без аргументов?
- •Пример: две версии класса Account
- •Функции с побочным эффектом
- •Методы. Перегрузка
- •10. Лекция: Корректность методов. Рекурсия
- •Корректность методов
- •Инварианты и варианты цикла
- •Рекурсия
- •Рекурсивное решение задачи "Ханойские башни"
- •Быстрая сортировка Хоара
- •11. Лекция: Массивы языка C#
- •Общий взгляд
- •Объявление массивов
- •Объявление одномерных массивов
- •Динамические массивы
- •Многомерные массивы
- •Массивы массивов
- •Процедуры и массивы
- •12. Лекция: Класс Array и новые возможности массивов
- •Класс Array
- •Массивы как коллекции
- •Сортировка и поиск. Статические методы класса Array
- •Класс Object и массивы
- •Массивы объектов
- •Массивы. Семантика присваивания
- •13. Лекция: Символы и строки постоянной длины в C#
- •Общий взгляд
- •Строки С++
- •Строки С#
- •Класс char
- •Класс char[] - массив символов
- •Существует ли в C# тип char*
- •14. Лекция: Строки C#. Классы String и StringBuilder
- •Класс String
- •Объявление строк. Конструкторы класса string
- •Операции над строками
- •Строковые константы
- •Неизменяемый класс string
- •Статические свойства и методы класса String
- •Метод Format
- •Методы Join и Split
- •Динамические методы класса String
- •Класс StringBuilder - построитель строк
- •Объявление строк. Конструкторы класса StringBuilder
- •Операции над строками
- •Основные методы
- •Емкость буфера
- •15. Лекция: Регулярные выражения
- •Пространство имен RegularExpression и классы регулярных выражений
- •Немного теории
- •Синтаксис регулярных выражений
- •Классы Group и GroupCollection
- •Классы Capture и CaptureCollection
- •Перечисление RegexOptions
- •Класс RegexCompilationInfo
- •Примеры работы с регулярными выражениями
- •Пример "чет и нечет"
- •Пример "око и рококо"
- •Пример "кок и кук"
- •Пример "обратные ссылки"
- •Пример "Дом Джека"
- •Пример "Атрибуты"
- •16. Лекция: Классы
- •Классы и ООП
- •Две роли классов
- •Синтаксис класса
- •Поля класса
- •Доступ к полям
- •Методы класса
- •Доступ к методам
- •Методы-свойства
- •Индексаторы
- •Операции
- •Статические поля и методы класса
- •Константы
- •Конструкторы класса
- •Деструкторы класса
- •Проектирование класса Rational
- •Свойства класса Rational
- •Конструкторы класса Rational
- •Методы класса Rational
- •Закрытый метод НОД
- •Печать рациональных чисел
- •Тестирование создания рациональных чисел
- •Операции над рациональными числами
- •Константы класса Rational
- •17. Лекция: Структуры и перечисления
- •Развернутые и ссылочные типы
- •Классы и структуры
- •Структуры
- •Синтаксис структур
- •Класс Rational или структура Rational
- •Встроенные структуры
- •Еще раз о двух семантиках присваивания
- •Перечисления
- •Персоны и профессии
- •18. Лекция: Отношения между классами. Клиенты и наследники
- •Отношения между классами
- •Отношения "является" и "имеет"
- •Отношение вложенности
- •Расширение определения клиента класса
- •Отношения между клиентами и поставщиками
- •Сам себе клиент
- •Наследование
- •Добавление полей потомком
- •Конструкторы родителей и потомков
- •Добавление методов и изменение методов родителя
- •Статический контроль типов и динамическое связывание
- •Три механизма, обеспечивающие полиморфизм
- •Пример работы с полиморфным семейством классов
- •Абстрактные классы
- •Классы без потомков
- •19. Лекция: Интерфейсы. Множественное наследование
- •Интерфейсы
- •Две стратегии реализации интерфейса
- •Преобразование к классу интерфейса
- •Проблемы множественного наследования
- •Коллизия имен
- •Наследование от общего предка
- •Встроенные интерфейсы
- •Упорядоченность объектов и интерфейс IComparable
- •Клонирование и интерфейс ICloneable
- •Сериализация объектов
- •Класс с атрибутом сериализации
- •Интерфейс ISerializable
- •20. Лекция: Функциональный тип в C#. Делегаты
- •Как определяется функциональный тип и как появляются его экземпляры
- •Функции высших порядков
- •Вычисление интеграла
- •Построение программных систем методом "раскрутки". Функции обратного вызова
- •Наследование и полиморфизм - альтернатива обратному вызову
- •Делегаты как свойства
- •Операции над делегатами. Класс Delegate
- •Операции "+" и "-"
- •Пример "Комбинирование делегатов"
- •Пример "Плохая служба"
- •21. Лекция: События
- •Классы с событиями
- •Класс sender. Как объявляются события?
- •Делегаты и события
- •Как зажигаются события
- •Классы receiver. Как обрабатываются события
- •Классы с событиями, допустимые в каркасе .Net Framework
- •Пример "Списки с событиями"
- •Класс sender
- •Классы receiver
- •Две проблемы с обработчиками событий
- •Игнорирование коллег
- •Переопределение значений аргументов события
- •Классы с большим числом событий
- •Проект "Город и его службы"
- •22. Лекция: Универсальность. Классы с родовыми параметрами
- •Наследование и универсальность
- •Синтаксис универсального класса
- •Класс с универсальными методами
- •Два основных механизма объектной технологии
- •Стек. От абстрактного, универсального класса к конкретным версиям
- •Ограниченная универсальность
- •Синтаксис ограничений
- •Список с возможностью поиска элементов по ключу
- •Как справиться с арифметикой
- •Родовое порождение класса. Предложение using
- •Универсальность и специальные случаи классов
- •Универсальные структуры
- •Универсальные интерфейсы
- •Универсальные делегаты
- •Framework .Net и универсальность
- •23. Лекция: Отладка и обработка исключительных ситуаций
- •Корректность и устойчивость программных систем
- •Жизненный цикл программной системы
- •Три закона программотехники
- •Первый закон (закон для разработчика)
- •Второй закон (закон для пользователя)
- •Третий закон (закон чечако)
- •Отладка
- •Создание надежного кода
- •Искусство отладки
- •Отладочная печать и условная компиляция
- •Классы Debug и Trace
- •Метод Флойда и утверждения Assert
- •Классы StackTrace и BooleanSwitch
- •Отладка и инструментальная среда Visual Studio .Net
- •Обработка исключительных ситуаций
- •Обработка исключений в языках C/C++
- •Схема обработки исключений в C#
- •Выбрасывание исключений. Создание объектов Exception
- •Захват исключения
- •Параллельная работа обработчиков исключений
- •Блок finally
- •Схема Бертрана обработки исключительных ситуаций
- •Класс Exception
- •Организация интерфейса
- •Форма и элементы управления
- •Взаимодействие форм
- •Модальные и немодальные формы
- •Передача информации между формами
- •Образцы форм
- •Главная кнопочная форма
- •Шаблон формы для работы с классом
- •Работа со списками (еще один шаблон)
- •Элемент управления класса ListBox
- •Наследование форм
- •Два наследника формы TwoLists
- •Огранизация меню в формах
- •Создание меню в режиме проектирования
- •Классы меню
- •Создание инструментальной панели с командными кнопками
- •Рисование в форме
- •Класс Graphics
- •Методы класса Graphics
- •Класс Pen
- •Класс Brush
- •Проект "Паутина Безье, кисти и краски"
- •Паутина Безье
- •Событие Paint
- •Кисти и краски
- •Абстрактный класс Figure
- •Классы семейства геометрических фигур
- •Класс Ellipse
- •Класс Circle
- •Класс LittleCircle
- •Класс Rect
- •Класс Square
- •Класс Person
- •Список с курсором. Динамические структуры данных
- •Классы элементов списка
- •Организация интерфейса
int b1=1;
Type t = b1.GetType();
Console.WriteLine("Тип переменной b1: {0}", t); //Console.WriteLine("Размер переменной b1: {0}", sizeof(t));
}//SizeMethod
В этом примере операция применяется к трем встроенным типам - bool, double, char. Консольный вывод дает в качестве результата значения: 1, 8 и 2. Обращаю внимание на то, что аргументом операции может быть только имя типа. Попытка применить эту операцию к переменной t типа Type, имеющей значение System.Int32, приводит к ошибке компиляции.
Операция typeof, примененная к своему аргументу, возвращает его тип. И здесь в роли аргумента может выступать имя класса, как встроенного, так и созданного пользователем. Возвращаемый операцией результат имеет тип Type. К экземпляру класса применять операцию нельзя, но зато для экземпляра можно вызвать метод GetType, наследуемый всеми классами, и получить тот же результат, что дает typeof с именем данного класса. Такой альтернативный способ получения типа по экземпляру класса int показан в приведенном выше программном фрагменте. А сейчас я приведу фрагмент, где используется вызов операции typeof:
t = typeof(Class1);
Console.WriteLine("Тип класса Class1: {0}", t); t = typeof(Testing);
Console.WriteLine("Тип класса Testing: {0}", t);
Как получить подробную информацию о классе?
Пожалуй, следует рассказать не только о том, как можно получить переменную типа Type, а и о том, что можно с этой переменной делать.
Этот и последующий раздел прерывают последовательное рассмотрение темы операций языка C#. Полагаю, понимание того, с какой целью выполняются те или иные операции, не менее важно, чем знание самой операции, И я не стал откладывать изложение этого материала на последующие лекции.
Можно ли, зная тип (класс), получить подробную информацию обо всех методах и полях класса? Ясно, что такая информация может быть весьма полезной, если класс поставлен сторонней фирмой. Оказывается, это сделать нетрудно. Вся необходимая информация содержится в метаданных, поставляемых вместе с классом. Процесс получения метаданных называется отражением (reflection). Об отражении и метаданных уже говорилось в первой вводной лекции, и эта тема будет обсуждаться и далее. А сейчас я приведу пример, демонстрирующий получение подробной информации о методах и полях класса. Первым делом следует упростить в проекте использование классов пространства имен Reflection, добавив в начало проекта предложение
using System.Reflection.
В класс Testing я добавил существенно расширенный вариант метода WhoIsWho, который уже появлялся в наших примерах. Вот текст новой версии этой процедуры:
///<summary>
///Подробная информация о классе объекта, его значении,
///методах класса, всех членов класса
///</summary>
///<param name="name">имя объекта</param>
///<param name="any">объект любого типа</param>
public void WhoIsWho(string name,object any)
{
Type t = any.GetType();
Console.WriteLine("Тип {0}: {1} , значение: {2}", name, any.GetType(), any.ToString());
Console.WriteLine("Методы класса:"); MethodInfo[] ClassMethods = t.GetMethods(); foreach (MethodInfo curMethod in ClassMethods)
{
Console.WriteLine(curMethod);
}
Console.WriteLine("Все члены класса:"); MemberInfo[] ClassMembers = t.GetMembers(); foreach (MemberInfo curMember in ClassMembers)
{
Console.WriteLine(curMember.ToString());
}
}//WhoIsWho
Коротко прокомментирую эту процедуру. Вначале создается переменная t типа Type. Значением этой переменной будет тип аргумента, переданного в процедуру в качестве значения параметра any. Напомню, any имеет базовый тип object и потому метод может быть вызван с аргументом, роль которого может играть выражение любого типа. Далее вызываются методы переменной t - GetMethods() и GetMembers(). Эти методы соответственно возвращают в качестве значений массивы элементов классов MethodInfo и MemberInfo. Эти классы содержатся в пространстве имен Reflection, они хранят информацию в первом случае о методах класса, во втором - о полях и методах класса, заданного переменной t. В пространстве имен Reflection имеются и другие классы, чьи методы и свойства полезны для получения дополнительной информации об исследуемом классе. Но я не буду сейчас столь подробно развивать эту тему.
В процедуре Main дважды вызывается процедура WhoIsWho. В первом вызове ее аргументом является выражение типа double, во втором - сам объект ts, вызывающий метод:
ts.WhoIsWho("2+2.5", 2+2.5); ts.WhoIsWho("ts", ts);
И класс double, и созданный в этом проекте класс Testing имеют довольно много методов. Имеют они и свойства. Процедура WhoIsWho выдаст подробную информацию обо всех элементах этих классов. Результаты консольного вывода, полученного при двух вызовах этой процедуры, показаны на рис. 6.2.
Рис. 6.2. Информация о классах int и Testing, полученная в процедуре WhoIsWho
Рассмотрим выводимую информацию о классах. Для созданного в проекте класса Testing отображается информация о полях и методах как собственных, так и наследуемых от общего родителя - класса Object. Заметьте, отображается информация только об открытых полях и методах класса, а поскольку поля нашего класса закрыты, то и информации о них нет.
Класс Int подробно обсуждался в предыдущей и в этой лекции. Все методы, которые могут вызывать переменные (объекты) класса Int, были уже рассмотрены. Тем не менее, из выводимой информации можно узнать и нечто новое, поскольку выдаются сведения и о статических полях и методах класса.
Статические поля и методы арифметических классов
Все арифметические классы, в том числе класс Int, обладают двумя полезными полями (свойствами) - MinValue и MaxValue. Эти поля возвращают минимальное и максимальное значение, которое могут иметь экземпляры класса. Поля являются статическими и потому недоступны для экземпляров класса и могут быть вызваны только при указании имени класса. Разумно привести пример вызова этих полей для класса Int и, например, для класса Double:
//Min и Max значения типов
Console.WriteLine("Class int");
Console.WriteLine("Мин. значение int = " + int.MinValue); Console.WriteLine("Макс. значение int = " + int.MaxValue); Console.WriteLine("Class double");
Console.WriteLine("Мин. значение double = " + double.MinValue); Console.WriteLine("Макс. значение double = " + double.MaxValue);
Все арифметические классы, в том числе класс Int, обладают перегруженным статическим методом Parse, у которого первым обязательным параметром является строка, задающая значение соответствующего арифметического типа в привычной для данного региона (локализованной) форме. Форматом строки и стилем ее представления
можно управлять с помощью других параметров метода Parse. Вот пример вызова этого метода для классов Int и Double:
///<summary>
///Преобразования типа с использованием метода Parse
///</summary>
public void Parsing()
{
//method Parse Console.WriteLine("Введите целое"); string strdata = Console.ReadLine(); int intdata = int.Parse(strdata);
Console.WriteLine("Введите число с дробной частью и порядком"); strdata = Console.ReadLine();
double doubdata = double.Parse(strdata); Console.WriteLine("intdata = {0}; doubdata = {1}",
intdata, doubdata);
}
//Parsing
Как видите, метод Parse с успехом заменяет соответствующий метод класса Convert.
На рис. 6.3 можно увидеть консольный вывод, полученный в результате работы процедуры Parsing.
Рис. 6.3. Результаты работы процедуры Parsing
Операция new
Пора вернуться к основной теме - операциям, допустимым в языке C#. Последней из еще не рассмотренных операций высшего уровня приоритета является операция new. Ключевое слово new используется в двух контекстах - как модификатор и как операция в инициализирующих выражениях объявителя. Во втором случае результатом выполнения операции new является создание нового объекта и вызов соответствующего конструктора. Примеров подобного использования операции new было приведено достаточно много, в том числе и в этой лекции.
Арифметические операции
В языке C# имеются обычные для всех языков арифметические операции - "+, -, *, /, %". Все они перегружены. Операции "+" и "-" могут быть унарными и бинарными. Операция деления "/" над целыми типами осуществляет деление нацело, для типов с плавающей и фиксированной точкой - обычное деление. Операция "%" определена над всеми арифметическими типами и возвращает остаток от деления нацело. Тип результата зависит от типов операндов. Приведу пример вычислений с различными арифметическими типами:
///<summary>
///Арифметические операции
///</summary>
public void Ariphmetica()
{
int n = 7,m =3, p,q; p= n/m; q= p*m + n%m;