- •5. Обзор встроенных типов данных в с#. Применение встроенной функциональности типов данных.
- •6. Пространство имён System. Класс System.Math
- •7.Операции ввода-вывода. Формат вывода.
- •8. Арифметические операции. Операции отношений и логические операции. Операторы и выражения в c# .
- •Операторы
- •9.Массивы в с#. Одномерные массивы.
- •10.Класс System.Random, применение его методов для создания массива случайных чисел. Класс System.Array, использование его методов и свойства Length.
- •11. Двумерныемассивы в c#. Виды двумерных массивов и способы их определения. Способы создания двумерных массивов. Вывод матриц на экран по строкам.
- •12. Структуры в c#. Создание структур. Массивы структур.
- •13.Объект и его свойства. Характеристики ооп.
- •14.Определение классов в c#. Члены класса. Форма определения класса.
- •15.Конструкторы. Параметризованные конструкторы. Создание экземпляра класса. Использование оператора new.
- •16. Типы значений и ссылочные типы. Динамическое использование памяти: стеки и кучи. Упаковка и распаковка.
- •18. Определение методов класса. Модификаторы доступа к методам класса. Параметры методов класса, передача аргументов.
- •19. Модификаторы ref, out, params параметров методов.
- •20.Возвращение методами объектов класса. Возвращение методами массивов Возвращение методами объектов класса
- •Возвращение методами массивов
- •21. Общие (статические) члены класса. Доступ к общим членам. Ограничения на static-методы.
- •22.Цикл «Жизни». Область видимости и время существования переменных.
- •23. Преобразование и приведение типов данных.
16. Типы значений и ссылочные типы. Динамическое использование памяти: стеки и кучи. Упаковка и распаковка.
Все типы в C# разделяются на две основные разновидности: структурные типы (value- based) или типы значений и ссылочные типы (reference- based).
Типы значений можно разделить на 3 группы: простые типы, структуры и перечисление. При присвоении одного структурного типа другому присваивается не сам тип (как область в памяти), а его побитовая копия. Выполнение операций с использованием типов значений происходит быстрее, чем при использовании ссылочных типов.
-
Память для структурных типов выделяется из стека:
Пример:
Стек резервируется для хранения данных, создаваемых во время выполнения программы. В стеке применяется принцип обслуживания типа LiFO (Last in First Out – последний пришел, первым обслужен). Согласно этому методу, первым обрабатывается последний из поступивших запросов.
2.Ссылочные типы (классы, интерфейсы, массивы, строки) хранят ссылки на данные, вместо действительных данных и ведут себя по-другому Память для ссылочных переменных выделяется в управляемой (динамической) куче. Ссылочная переменная содержит информацию о месте хранения, т.е. ссылку на данные. Когда операционная система запускает приложение на выполнение, CLR резервирует непрерывный диапазон адресов адресного пространства, который называют управляемой кучей. Выделение памяти из кучи в среде .NET происходит очень быстро. После того как приложение использует оператор new для создания объекта, CLR проверяет, доступно ли в куче необходимое количество байт для запрашиваемого объекта. Система возвращает указатель на эту память и переводит указатель на следующий после последнего объекта адрес. В начальный момент, когда в куче ещё нет ни одного объекта, этот указатель указывает на базовый адрес зарезервированного адресного пространства.
Пример:
Ссылки указывают на местонахождение объектов в управляемой куче. Когда много создано объектов, пространство в управляемой куче может закончиться. Тогда автоматически запускается сборщик мусора. Он отслеживает, есть ли в куче активные ссылки. Если ссылок на объект нет или объект установлен на null, то объект помечается для удаления.
При копировании ссылочного типа создаётся ещё одна ссылка, которая указывает на туже область оперативной памяти. Можно изменить исходный объект: ob1= ob2;
Обе переменные ob1 и ob2 ссылаются на один и тот же объект. На этот объект можно воздействовать, используя либо ob1, либо ob2.
Рекомендуется не создавать много объектов класса, т.к память может закончиться, а переустанавливать значение старых объектов с помощью метода set(…).
От структурного типа к ссылочному типу и наоборот: упаковка и распаковка. В C# предусмотрен очень простой механизм для преобразования структурного типа в ссылочный. Он получил название упаковки (boxing). Предположим, что у нас есть переменная простого структурного типа данных short: short S=25;
А вот как выглядит процесс упаковки – преобразование объекта структурного типа в ссылочный: object objshort=s;
Упаковка – это процесс явного преобразования структурного типа в ссылочный. При этом происходит следующее: в управляемой куче создаётся новый объект и в него копируются внутренние данные старого объекта из стека (число 25).
Противоположная операция называется распаковкой (unboxing). Распаковка – это преобразование ссылки на объект в оперативной памяти обратно в структурный тип. Перед выполнением распаковки среда выполнения CLR производит проверку на совместимость между типом объекта в оперативной памяти и тем структурным типом, в который будет производиться распаковка: short anotherShort=(short) obj’short;
Если же среда выполнения обнаружит, что происходит распаковка в неподходящий тип данных, будет сгенерировано исключение InvalidCastException (Неверная распаковка).
Когда нужно заниматься упаковкой и распаковкой? Ответ – не слишком часто. В подавляющем большинстве случаев операции по упаковке и распаковке выполняются компилятором в C# полностью автоматически
17. Сбор «мусора» и использование деструктора.
Деструктор – это специальный метод, который вызывается перед тем, как объект будет окончательно разрушен системой сбора мусора. Он обеспечивает гарантию «чистой» ликвидации объекта. Деструктор используется для операций освобождения памяти, выделенной для объектов класса.
Формат записи деструктора:
Имя_класса ~( )
{
// тело деструктора
}
Характеристики деструктора:
1) имя деструктора совпадает с именем класса;
2) для деструктора неявно устанавливается спецификатор доступа public;
3) деструктору нельзя передать аргументы, поэтому в классе может быть определён только один деструктор.
Деструктор не возвращает значения. Он вызывается в момент, предшествующий процессу утилизации объекта. В теле деструктора указываются действия, которые должны быть выполнены перед разрушением объекта.
Сбор мусора.
Управление ресурсами в программе может оказаться довольно сложной задачей. Как правило, в приложении задействовано значительное количество ресурсов, например, записи баз данных, сетевые соединения, пространство экрана монитора и т.д. В ситуации, когда после использования памяти, выделенной для ресурса, она не освобождается, или доступ к ресурсу продолжается несмотря на освобождение памяти, работа приложения становится нестабильной и непредсказуемой. Для предотвращения подобных проблем разработана программа сборщика мусора. Сборщик мусора – один из наиболее важных компонентов среды CLR. Он освобождает программиста от утомительной задачи контроля использования и своевременного освобождения памяти.
Однако в некоторых ситуациях нужно разрабатывать собственные деструкторы. Например, если программист установил сетевое соединение и больше не нуждается в нём, то сборщику мусора не будет известно о необходимости разрыва сетевого соединения до освобождения области памяти, выделенной для этого соединения. Поэтому программист должен в программном коде написать, как правильно следует освобождать ресурс. В среде .NET программисты создают такой код с помощью деструктора или методов Close или Dispose.
Сборщик мусора освобождает память, занимаемую неиспользуемыми объектами. Иными словами, при удалении последней ссылки на объект он становится кандидатом на удаление сборщиком мусора. Процесс вызова деструктора или прекращение дальнейшего использования объекта называют завершением (finialzation).
Основная проблема сборки мусора заключена в том, что невозможно точно предсказать, когда сборщик мусора освободит память. Обычно это происходит при недостатке объёма памяти для хранения данных создаваемых объектов. В результате могут возникнуть ситуации, когда деструктор объекта вообще не буде вызван. Даже на этапе завершения работы приложения CLR может пропустить процесс вызова деструктора объекта с целью ускорения завершения работы. Поэтому рекомендуется не выполнять операции освобождения памяти с помощью деструктора. Желательно создать отдельный метод, в который можно добавить операции по завершению работы (например, закрытие файла или обновление записей в базе данных). Затем необходимо определить явный вызов этого метода.
