Как правильно писать тесты 46 Цикл разработки 46 Структура проекта с тестами 51 Утверждения (Asserts) 52 Утверждения в форме ограничений 54 Категории 56
Вид материала | Тесты |
СодержаниеИнициализаторы переменных |
- Некорректные задания, 1276.79kb.
- К техническому регламенту, 835.7kb.
- Правительства Российской Федерации от 11 ноября 2005 г. N 679 о порядке разработки, 494.44kb.
- Постановлением Правительства Российской Федерации от 11 ноября 2005 г. N 679 о порядке, 652.85kb.
- Постановлением Правительства Российской Федерации от 11 ноября 2005 г. N 679 о порядке, 623.18kb.
- Правительства Российской Федерации от 11. 11. 2005 N 679 о порядке разработки и утверждения, 533.6kb.
- Постановления Правительства Российской Федерации от 11. 11. 2005 n 679 о порядке разработки, 613.63kb.
- Об утверждении требований к схемам теплоснабжения, порядку их разработки и утверждения, 450.79kb.
- Рабочая программа учебной дисциплины. Общие требования, порядок разработки, согласования, 414.77kb.
- Постановлением Правительства Российской Федерации от 11 ноября 2005 г. N 679 о порядке, 1924.26kb.
Инициализаторы переменных
У классов зачастую имеется более одного конструктора. С течением времени синхронизация элементов класса и конструкторов может быть нарушена. Чтобы этого не происходило, следует инициализировать переменные при их объявлении, а не в теле каждого из конструкторов. Синтаксис инициализаторов следует применять и для статических переменных, и для переменных экземпляра.
Конструирование элементов класса при объявлении переменных является в С# совершенно естественным:
public class MyClass
{
// declare the collection, and initialize it.
private ArrayList _coll = new ArrayList( );
}
Вне зависимости от числа конструкторов, которые будут с течением времени добавлены в тип MyClass, переменная _coll будет инициализирована надлежащим образом. В начале каждого конструктора компилятор генерирует программный код для выполнения всех инициализаторов, определенных для элементов объекта-экземпляра. При добавлении нового конструктора переменная _coll остается инициализированной. Аналогично, если добавляется новое поле класса, не нужно добавлять код инициализации к каждому конструктору; достаточно инициализировать переменную там, где она определяется. Важно и то, что инициализаторы добавляются к генерируемому компилятором конструктору по умолчанию. Компилятор С# создает для классов конструктор по умолчанию, если для них явно не определено ни одного конструктора.
Инициализаторы представляют собой нечто большее, чем сокращенная запись действий в теле конструктора. Операторы, генерируемые инициализаторами, помещаются в код объекта перед телом конструкторов. Инициализаторы выполняются перед исполнением базовых конструкторов для типа и в том порядке, в котором были объявлены переменные в вашем классе.
Использование инициализаторов является простейшим способом избежать появления в типах неинициализированных переменных, но этот способ несовершенен. Есть три случая, когда не следует использовать синтаксис с инициализацией. Первый из них — это случай, когда необходимо инициализировать объект нулевыми (0) или пустыми (null) значениями. Используемая по умолчанию системная инициализация устанавливает все значения в 0 перед началом выполнения любого программного кода. Генерируемая системой инициализация выполняется на низком уровне, непосредственно используя команды CPU для установки в 0 целых блоков памяти. Поэтому любая предпринимаемая разработчиком дополнительная инициализация нулями будет излишней. Компилятор С# покорно добавит дополнительные команды для еще одной установки памяти в 0. Это не является ошибкой — просто это неэффективно. На самом деле, если задействованы типы-значения, это будет очень неэффективно.
MyValType _MyVal1; // initialized to 0
MyValType _MyVal2 = new MyValType(); // also 0
Оба оператора инициализируют переменную нулями. В первом операторе это достигается путем установки памяти, содержащей MyVall, в 0. Во втором операторе используется команда IL initobj, которая приводит к выполнению для переменной MyVal2 операций упаковки и распаковки. Для этого требуется чуть больше времени.
Второй случай, когда не следует использовать синтаксис с инициализацией, имеет место, если для одного и того же объекта создается несколько инициализаций. Синтаксис инициализации следует применять только для переменных, которые во всех конструкторах получают одинаковую инициализацию. В следующей версии MyClass как часть его конструирования могут быть созданы два различных объекта ArrayList:
public class MyClass
{
// declare the collection, and initialize it.
private ArrayList _coll = new ArrayList( );
MyClass( )
{
}
MyClass( int size )
{
_coll = new ArrayList( size );
}
}
Когда создается новый объект MyClass с заданным размером коллекции, строятся два списка массивов. Один из них немедленно становится мусором. Инициализатор переменной выполняется раньше любого конструктора. В теле конструктора создается второй список массивов. Компилятор создает версию MyClass, которую вы никогда не написали бы вручную.
public class MyClass
{
// declare the collection, and initialize it.
private ArrayList _coll;
MyClass( )
{
_coll = new ArrayList( );
}
MyClass( int size )
{
_coll = new ArrayList( );
_coll = new ArrayList( size );
}
}
И последняя причина переноса инициализации в тело конструктора — это упрощение обработки исключительных ситуаций. Инициализаторы не могут быть заключены в оболочку блока tгу. Любые исключительные ситуации, которые могут быть сгенерированы во время конструирования объекта для поля класса, распространяются за пределы объекта. Невозможно предпринять какое-то восстановление вне методов класса. Следует переместить код инициализации в тело конструкторов, чтобы реализовать подходящий код для обработки исключительной ситуации.
Инициализаторы переменных служат гарантией того, что объекты-экземпляры класса в вашем типе инициализируются вне зависимости от того, какой конструктор был вызван. Инициализаторы выполняются перед каждым созданным для вашего класса конструктором. При использовании этого синтаксиса ваш код не останется без соответствующей инициализации, если вы в будущем добавите новый конструктор. Применяйте инициализаторы в тех случаях, когда все конструкторы создают объекты для полей класса одним и тем же способом; это облегчает чтение и поддержку.
Содержание 1
Процесс разработки программного обеспечения 3
Основные принципы объектно-ориентированного программирования (начало) 12
История 14
Основные принципы объектно-ориентированного программирования (продолжение) 15
Главные понятия 15
Основные принципы 15
Абстракция данных 15
Инкапсуляция 16
Наследование 16
Основные принципы объектно-ориентированного программирования (окончание) 18
Полиморфизм 18
Отношения 19
Основы .NET Framework 22
Введение 22
Обзор выполнения кода в среде CLR 26
Компиляция исходного кода в управляемые модули 26
Части управляемого модуля 28
Объединение управляемых модулей в сборку 29
Загрузка CLR при выполнении программы 31
Исполнение кода сборки 31
IL и верификация 36
Небезопасный код 36
IL и защита интеллектуальной собственности 37
NGen.exe — генератор объектного кода 38
Библиотека классов .NET Framework 38
Общая система типов (Common Type System, CTS) 40
Общеязыковая спецификация 42
Модульное тестирование (unit testing) 44
Предпосылки 44
Преимущества 44
Поощрение изменений 45
Упрощение интеграции 45
Документирование кода 45
Отделение интерфейса от реализации 45
Ограничения 46
Как правильно писать тесты 46
Цикл разработки 46
Структура проекта с тестами 51
Утверждения (Asserts) 52
Утверждения в форме ограничений 54
Категории 56
Настройка среды выполнения тестов 57
Дополнительные утверждения 59
Тесты и исключения 60
Правила тестирования 62
Юнит-тестирование 70
Пример 70
Два вида констант 98
Операторы is, as и приведение типов 101
Метод ToString() 109
Типы-значения и ссылочные типы 117
Неизменяемые (Immutable) атомарные типы-значения 122
0 в типах-значениях 132
Методы ReferenceEquals(), Equals(), статический метод Equals() и operator== 134
Циклы foreach 140
Управление ресурсами в .NET 143
Инициализаторы переменных 149
Инициализация статических полей классов с помощью статических конструкторов 155
Цепочки конструкторов 157
Применение операторов using и try/finally для освобождения ресурсов 160
О минимизации мусора 167
Упаковка и распаковка 169
Наследование классов и реализация интерфейсов 171
Отличие реализации методов интерфейса от переопределения виртуальных методов 178
Введение в паттерны проектирования 184
Что такое паттерн проектирования 186
Паттерны проектирования в схеме MVC 188
Описание паттернов проектирования 190
Каталог паттернов проектирования 192
Как решать задачи проектирования с помощью паттернов 195
Механизмы повторного использования 204
Сравнение структур времени выполнения и времени компиляции 210
Проектирование с учетом будущих изменений 212
Как выбирать паттерн проектирования 220
Как пользоваться паттерном проектирования 221
Делегаты и события 226
Делегаты 226
События 230
Параметры событий 233
Атрибуты 237
Синтаксис 237
Создание атрибута 240
Составляющие класса атрибута 242
Получение значений атрибута 244
Задание 1 245
Задание 2 246
Обобщения 251
Проблемы создания объектных образов и восстановления значений 252
Типовая безопасность и строго типизованные коллекции 253
Проблемы создания объектных образов и строго типизованные коллекции 258
Пространство имен System.Collections.Generic 259
Тип List
Создание обобщенных методов 263
Пропуск параметров типа 265
Создание обобщенных структур (и классов) 267
Ключевое слово default в обобщенном программном коде 269
Создание пользовательских обобщенных коллекций 271
Установка ограничений для параметров типа с помощью where 274
Отсутствие поддержки ограничений при использовании операций 279
Создание обобщенных базовых классов 280
Создание обобщенных интерфейсов 282
Создание обобщенных делегатов 284
Несколько слов о вложенных делегатах 286
Задачи 286
Примеры реализации по шаблонам Мост+Фабрика 289
Пример 1 289
Пример 2 292
Пример 3. Контроллер в виде интерфейса, а не класса. 294
Различное поведение фабрик 298
Фабрики для создания плагинов 299
Фабрики для создания объектов по некоторому алгоритму 300
Фабрики для клонирования объектов 300
Некоторые замечания об использовании свойств и наследования 302
Замечания об использовании свойств 302
Замечания об использовании наследования. Проблема «хрупкого» базового класса. 304