lect_2013_06_11.ppt
- Количество слайдов: 65
Курс. NET
Орг. вопросы • Просьба отметиться в учете посещаемости • Посещаемость нужна для статистики и не более. Просьба не вписывать себя повсеместно. (нужно знать количество стульев) • Включить камеру • Группа в контакте – «Симбирсофт_Шарп_2013»
Хорошая книга • Продуктивный программист. Как сделать сложное простым, а невозможное возможным • Нил Форд
Хорошая книга • Джон Роббинс • Отладка приложений для Microsoft. NET
Небольшой мой косячок • Начали пользоваться тестами • Что это такое и зачем это надо?
Академический мир (как нас учат) • Студент действует как лицо, конкурирующее с другими лицами, а групповая деятельность часто воспринимается как попытка мошенничества • Отдельной личности воздается хвала за её успехи • Студенты, пользующиеся чужими работами воспринимаются в лучшем случае с подозрением • Списывание осуждается
Мир производства (работа) • Наемный работник действует как член команды и групповая деятельность имеет преобладающее значение • Роль отдельной личности часто теряется в безвестности • Использование чужой работы – проявление здравого смысла • В промышленном мире делать новые документы путем копирования части старых документов считается правильным и разумным
Академический мир • Студент действует как лицо, конкурирующее с другими лицами, а групповая деятельность часто воспринимается как попытка мошенничества • Отдельной личности воздается хвала за её успехи • Студенты, пользующиеся чужими работами воспринимаются в лучшем случае с подозрением • Списывание осуждается Мир производства • Наемный работник действует как член команды и групповая деятельность имеет преобладающее значение • Роль отдельной личности часто теряется в безвестности • Использование чужой работы – проявление здравого смысла • В промышленном мире делать новые документы путем копирования части старых документов считается правильным и разумным
«Вечные вопросы» Россия • Кто виноват? • Что делать? • Когда будут хорошие дороги? Вопросы программирования • • Кто виноват? Что поломали? Когда поломали? А что все же еще работает?
Что делать, что бы восстановить программу? отлаживать
Начало отладки
После 8 ми часов отладки
Пути решения проблем (или как избежать 8 ми часовой отладки) • Методологии – Тяжеловесные – Легковесные
Легкие методологии • Экстремальное программирования • Суть – работающая программа – самое главное – Рядом сидит заказчик. – Ошибки в требованиях нормальные. После обнаружения исправляются «на живом» , а тесты помогают понять что еще задели, а что не задели – Быстрый отклик
Легкие методологии (критика) • Делаем программу для атомного реактора по быстрой методологии – Пусть закралась ошибка в программе – Будет ОЧЕНЬ быстрый отклик после внедрения ПО с ошибкой (и красивый «грибок» в придачу) – Нужна новая команда разработчиков (и желательно продолжать все в другой стране)
Когда не применимы легкие методологии? • Когда срок проекта – 5 лет и более (для всей команды). • Такие проекты – «динозавры» , их очень мало (если еще и есть). • Причина – мир меняется очень быстро и нет времени ждать пять лет • Остальное – очень хорошо частично ложатся на мягкие методологии • Методология – это не обязательство!!!!
Рассуждение о знании • В современных системах «сам черт не разберется» . • Как быть? Документировать требования к системам (книга от прошлого занятия), из требований получать трассы использования, их отладить. Извращаться (или отдать тестерам) – P. S. Возможно иногда имеет смысл разработчика посадить близко к двери
Одна из методологий - TDD • TDD - test-driven development • Суть: – Составили тест – Убедились, что он не работает – Сделали так, что бы работал – Закоммитили (занести в svn, git, mercurial и т. д. )
Плюсы TDD. Вы – первый пользователь программы и вы делаете автоматический её так, что бы вам было удобно
Тесты запустить повторно – легко и быстро. И может сделать другой
Можно разрабатывать по частям с Io. C (и параллельно) - придти к соглашению по правилам взаимодействия
Другие плюсы • Использование при continuous integration • И др.
Как составлять тесты? • Теория – надо составлять на все • Практика – не надо составлять на все (вернее надо, но времени не хватит)
Как составлять тесты? • Так что бы ошибку в тесте при отладке можно было найти за пару минут • Психология человека – надо видеть, что или продвигаемся или хотя бы не поломали • В начале составляем простые тесты, потом – добавляем более сложные • Желательно сделать некоторый приоритет выполнения тестов или сделать это в именовании тестов
Минусы тестов • В начале надо будет подготовить инфраструктуру тестирования (особенно плохо, когда заказчик предоставляет свою БД + vpn) • Можно обойти с использованием транзакций • Но в функциональных тестах все равно не обойти
Тесты • Обратить внимание на то, что получается в sln и как ищутся тесты. Создавать надо не библиотеки, а сразу тесты. • Работают на атрибутике (что будет рассмотрено позже) • Инициализация • Завершение • Перемешивание при запусках
Как запустить второй экземпляр программы для отладки? • Debug->Start new instance
• • • Стандартные коллекции Array (массив) List (список) Dictionary (словарь) Array. List (маразм) Hashtable (хэш-таблица) Tuple (кортеж) Bit. Array (битовый массив) Stack (стэк) Queue (очередь)
Тип object • Базовый класс для всех типов Object String Exception System. Exception My. Class
Стандартные методы • Все в C# имеет как минимум 4 метода: – To. String method – Equals method – Get. Type method – Get. Hash. Code method – Ошибка перегрузки только одного из Get. Hash. Code и Equals – поиск эквивалентных в хэше
Использование Private конструкторов • По сути – блокировка создания того, что не должно быть создано. • Статические методы класса могут вызываться public class Math { public static double Cos(double x) {. . . } public static double Sin(double x) {. . . } private Math( ) { } }
Управление ресурсами • • Очистка объектов Проблемы в временем вызова деструктора IDisposable Interface and Dispose Method The using Statement in C# using (Resource r 1 = new Resource( )) { r 1. Method( ); }
Расширение (наследование) классов • Класс-наследник не может быть более «доступным» чем базовый класс class Token { Derived class Base class. . . } class Comment. Token: Token {. . . Colon } Token « concrete » Comment. Token « concrete »
Вызов конструктора базового класса class Token { protected Token(string name) {. . . } class Comment. Token: Token { public Comment. Token(string name) : base(name) { }. . . }
Объявление виртуальных методов • public virtual string Name() { • … • } • Виртуальные методы являются одним из способов реализации полиморфизма • To use virtual methods: – You cannot declare virtual methods as static – You cannot declare virtual methods as private
Переопределение (Overriding) метода • Syntax: Use the override keyword class Token {. . . public virtual string Name( ) {. . . } } class Comment. Token: Token {. . . public override string Name( ) {. . . } }
Использования new для скрытия методов • Syntax: Use the new keyword to hide a method • Если используется – проблемы архитектуры, поэтому лучше избегать class Token {. . . public int Line. Number( ) {. . . } } class Comment. Token: Token {. . . new public int Line. Number( ) {. . . } }
Использование Sealed классов • Нельзя делать наследование от sealed класса. • Многие. NET Framework типы уже sealed: String, String. Builder, and so on • Но sealed классы можно расширять через методырасширители • Синтаксис: использовать ключевое слово sealed namespace System { public sealed class String {. . . } } namespace Mine { class Fancy. String: String {. . . } } û
Объявление интерфейсов • Syntax: Use the interface keyword to Interface names should declare methods begin with a capital “I” interface IToken { int Line. Number( ); string Name( ); } No access specifiers No method bodies IToken « interface » Line. Number( ) Name( )
Раннее и позднее связывание • Вызов обычных методов определяется во время компиляции. • Вызов виртуальных методов определяется во время выполнения программы Musician « interface » Tune. Your. Instrument( ) runtime Violin Player « concrete » Tune. Your. Instrument( ) Late binding (позднее связывание) Early binding (ранее связывание)
Множественная реализация интерфейсов interface IToken { IToken IVisitable string Name( ); « interface » } interface IVisitable { void Accept(IVisitor v); } Token class Token: IToken, IVisitable {. . . « concrete » } • • Класс может реализовывать ноль или более интерфейсов Интерфейс может расширять ноль или более интерфейсов Класс может быть более доступным, чем интерфейсы Интерфейсы не могут быть более доступными, чем их базовые интерфейсы
Реализация методов интерфейса • Методы-реализаторы могут быть как виртуальными, так и не виртуальными class Token: IToken, IVisitable { public virtual string Name( ) {. . . } public void Accept(IVisitor v) {. . . } } Same access Same return type Same name Same parameters
Полное именование при реализации интерфейса class Token: IToken, IVisitable { string IToken. Name( ) {. . . } void IVisitable. Accept(IVisitor v) {. . . } } • Ограничения явного указания интерфейса: – Можно иметь доступ только через интерфейс – Методы не могут быть виртуальными – Нельзя указывать аксессор доступа
Объявление абстрактного класса abstract class Token {. . . } class Test { static void Main( ) { new Token( ); } } û Token { abstract } Нельзя создать экземпляр абстрактного класса
Сравнение абстрактных классов и интерфейсов • Схожести – Экземпляры нельзя создать – Они не могут быть sealed • Разница – Интерфейсы не могут содержать реализацию – Интерфейсы не могут содержать не public аксессор доступа – Интерфейсы не могут расширять не интерфейсы
Реализация абстрактных методов abstract class Token { public virtual string Name( ) {. . . } public abstract int Length( ); } class Comment. Token: Token { public override string Name( ) {. . . } public override int Length( ) {. . . } } • Синтаксически: использовать abstract • Только абстрактные классы могут содержать абстрактные методы • Абстрактные методы не могут иметь реализацию
Comparing Aggregation to Inheritance • Aggregation Part – Specifies an object relationship – A weak whole-to-part dependency. Whole – Dynamically flexible • Inheritance Base – Specifies a class relationship – A strong derived-to-base dependency Derived – Statically inflexible
Фабрика классов public class Bank { public Bank. Account Open. Account( ) { Bank. Account opened = new Bank. Account( ); accounts[opened. Number( )] = opened; return opened; } private Hashtable accounts = new Hashtable( ); } public class Bank. Account { internal Bank. Account( ) {. . . } public long Number( ) {. . . } public void Deposit(decimal amount) {. . . } }
Полная спецификация имени класса • Полное имя класса включает в себя и пространство имен namespace Vendor. A { public class Widget {. . . } class Application { static void Main( ) { Widget w = new Widget( ); Vendor. A. Widget w = new Vendor. A. Widget( ); } } û
Использование using namespace Vendor. A. Suite. B { public class Widget {. . . } } using Vendor. A. Suite. B; class Application { static void Main( ) { Widget w = new Widget( ); } }
Использование «using-alias» • Можно использовать псевдоним класса namespace Vendor. A. Suite. B { public class Widget {. . . } } using Widget = Vendor. A. Suite. B. Widget; class Application { static void Main( ) { Widget w = new Widget( ); } }
Assemblies Reflector, . NET Reactor и necrobit • Группа совместных классов – Повторно используемая, версионная и безопасная • Появляется возможность физического контроля доступа public internal private an assembly of four classes
Создание сборок (Assemblies) • Однофайловые сборки csc /target: library /out: Bank. dll Bank. cs Account. cs • Многофайловые сборки csc /t: library /addmodule: Account. netmodule /out: Bank. dll Bank. cs
Операторы C# (формальная классификация, которая никому не нужна ) Operator Categories Арифметические (Arithmetic) Логические (Logical) (Boolean and bitwise) Строковые (String concatenation) Increment and decrement Индексация (Indexing) Преобразования (Cast) Условные операторы (Conditional) Сдвиг (Shift) Делегаты (Delegate concatenation and removal) Отношения (Relational) Создание объекта (Object creation) Присвоемения (Assignment) Информация о типе (Type information) Работа с исключениями(Overflow Адресные (Indirection and exception control) address)
Перегрузка операторов public static Time operator+(Time t 1, Time t 2) { int new. Hours = t 1. hours + t 2. hours; int new. Minutes = t 1. minutes + t 2. minutes; return new Time(new. Hours, new. Minutes); }
Перегрузка операторов отношения Проблемы Get. Hash. Code при добавлении в Hash • Надо перегружать парами – < and > – <= and >= – == and != • Надо переопределить Equals если перегружаются == и != • Переопределить Get. Hash. Code, если переопределяется equals
Определение операторов преобразования public static explicit operator Time (float hours) {. . . } public static explicit operator float (Time t 1) {. . . } public static implicit operator string (Time t 1) {. . . } • Если класс определяет оператор преобразования в строку, то надо переопределить метод To. String()
Делегаты, Использование делегатов No Method Body public delegate void Start. Pump. Callback( ); . . . Start. Pump. Callback callback; . . . callback = new Start. Pump. Callback(ed 1. Start. Electric. Pump. Running); . . . callback( ); No Call Here
Как работают события • Событие – многоадресный делегат • Генератор события (Publisher) – Генерирует событие, оповещая подписчиков • Подписчики (Subscriber) – Предоставляет метод, который должен быть вызван при генерации события (порядок вызова по определению. NET не гарантируется)
События • Определение события public delegate void Start. Pump. Callback( ); private event Start. Pump. Callback Core. Overheating; • Подписывание на событие Pneumatic. Pump. Driverto an event • Subscribing pd 1 = new Pneumatic. Pump. Driver(. . . ); Core. Overheating += new Start. Pump. Callback(pd 1. Switch. On); • Вызов события (а в VB нет проверки) public. Notifying subscribers to an event void Switch. On. All. Pumps( • (Core. Overheating != null)){{ if Core. Overheating( ); } }
Что курили в MS? • При сериализации сохраняется весь граф объектов. Если у элемента есть событие, то сохраняются и все подписчики на событие • Что бы остановить сериализацию «по событию» надо добавить атрибут для field на event • При этом если не написать field, то не скомпилируется
Классическая ошибка • Задача: Надо отменить действие если сейчас 10 минут. • Где ошибка?
Зачем использовать свойства? • Удобно инкапсулировать логику обработки данных • Гибкость • Можно понять какой …. Изменил значение переменной при отладке class Button { public string Caption // Property { get { return caption; } set { caption = value; } } private string caption; // Field }
Сравнение свойств и полей • Свойства являются «логическими» полями – При использовании get аксессора можно вычислить возвращаемое значение, включив туда какую-либо логику • Сходства – синтаксис одинаков (использования) • Разница – Свойства не имеют значений, поэтому у них нет адреса – Свойства не могут быть использованы в качестве ref или out параметров
Рассказать про Stack. Frame • На самом деле свойства в конечном счете – две функции • И для «пикантности» в Release версии стек может отличатся от стека в Debug версии в зависимости от случайного числа
lect_2013_06_11.ppt