Слайд 2Автор материала: Семён Факторович, НГУ
оф. сайт курса: http://bit.ly/nsudotnet
Слайд 3Сегодня в программе
Немного о ключевом слове static и пространствах имен
(namespaces)
Ссылки (references): куда подевались мои указатели?
Reference types и value types
(очень важный момент)
Fields vs. properties, или кто такие геттеры и сеттеры?
Слайд 5Ключевое слово static
Вместо глобальных переменных — статические поля
Слайд 6Ключевое слово static
Вместо глобальных переменных — статические поля
Слайд 7Ключевое слово static
Вместо глобальных функций — статические методы классов
Слайд 8Ключевое слово static
Вместо глобальных функций — статические методы классов
Слайд 9Пространства имен
Namespace — способ группировки классов
Слайд 10Пространства имен
Namespace — способ группировки классов
Слайд 11Пространства имен
Пространства имен могут быть вложенными
Слайд 19Ссылки (references)
Стековая память
Динамическая память
Слайд 20Ссылки (references)
Стековая память
Быстро выделяется
Связана с текущим потоком исполнения
Ограничена: 1МБ на
поток
Очищается при выходе из метода
Слайд 21Ссылки (references)
Динамическая память (heap, куча)
Выделяется не так быстро
Связана с текущим
процессом
Ограничена только физическим объемом оперативной памяти
Очищается вручную (или сборщиком мусора)
Слайд 26Ссылка (reference)
Содержит адрес объекта в managed heap
Слайд 27Ссылка (reference)
Содержит адрес объекта в managed heap
Единственный* способ доступа к
объектам (нет разделения «указатель/ссылка», как в C++)
Слайд 28Ссылка (reference)
Содержит адрес объекта в managed heap
Единственный* способ доступа к
объектам (нет разделения «указатель/ссылка», как в C++)
На 32bit архитектуре —
4 байта
На 64bit архитектуре — 8 байт
Слайд 29Ссылка (reference)
Содержит адрес объекта в managed heap
Единственный* способ доступа к
объектам (нет разделения «указатель/ссылка», как в C++)
На 32bit архитектуре —
4 байта
На 64bit архитектуре — 8 байт
* Если очень хочется — то можно пользоваться указателями: см. unsafe. Применяется обычно для взаимодействия с нативными Win32 DLL
Слайд 32Оператор сравнения ==
Сравниваются ссылки, а не объекты!
Слайд 35Оператор присваивания =
Теперь обе ссылки указывают на один объект.
Копирования
полей не происходит!
Слайд 37Передача параметров в функцию
Естественно, по ссылке (никакого копирования)
Слайд 38Передача параметров в функцию
Естественно, по ссылке (никакого копирования)
Слайд 39Передача параметров в функцию
Естественно, по ссылке (никакого копирования)
Слайд 40Передача параметров в функцию
А если хочется так?
Слайд 41Передача параметров в функцию
А если хочется так?
Слайд 42Передача параметров в функцию
Ключевое слово ref
Слайд 43Передача параметров в функцию
Ключевое слово ref
Слайд 44Передача параметров в функцию
Вариант поинтереснее: out, обязательное присвоение значения
Слайд 45Передача параметров в функцию
Вариант поинтереснее: out, обязательное присвоение значения
Слайд 46Передача параметров в функцию
Вариант поинтереснее: out, обязательное присвоение значения
Часто применяется,
когда нужно вернуть и объект-результат, и код ошибки
string str
= "42";
int num;
bool isNumber = int.TryParse(str, out num);
Слайд 49Ссылки (references)
Почти всё, с чем вы будете работать — это
ссылки
Слайд 53А как быть с простыми типами?
Есть ссылочные типы (reference types)
А
есть понятие «тип-значение», value type
Слайд 54Value types
int – это value type, «тип-значение»
Слайд 55Value types
int – это value type, «тип-значение»
Всегда создается на стеке*
Слайд 56Value types
int – это value type, «тип-значение»
Всегда создается на стеке*
Сравнивается
по значению, побитово
Слайд 57Value types
Оператор присваивания действительно присваивает
Слайд 58Value types
При передаче в функцию аргумент копируется
int i
= 5;
Increment(i);
// i == 5
Слайд 59Value types
ref и out также работают
int i = 5;
Increment(ref i);
// i
== 6
Слайд 60Value types
Понятия null для value types нет
Слайд 61Value types vs. reference types
Value types:
Всегда создаются на стеке
Передаются в
функцию по значению
Присваиваются и сравниваются как интегральные типы
Не могут быть
равны null
Слайд 62Value types vs. reference types
Value types:
Всегда создаются на стеке*
Передаются в
функцию по значению
Присваиваются и сравниваются как интегральные типы
Не могут быть
равны null
Reference types:
Всегда создаются в куче
Передаются в функцию по ссылке
Присваиваются и сравниваются ссылки, а не сами объекты
Могут быть равны null
Слайд 63Value types vs. reference types
Value types:
Все числовые типы (int, float,
double, …)
Примитивные типы (bool, char)
DateTime, TimeSpan
Guid
Enum
Слайд 64Value types vs. reference types
Value types:
Все числовые типы (int, float,
double, …)
Примитивные типы (bool, char)
DateTime, TimeSpan
Guid
Enum
Reference types:
Всё остальное
string (NB!)
Слайд 65Value types vs. reference types
Value type — полноценный класс: методы,
статические поля, наследование от интерфейсов, etc.
Для value types работает оператор
new и можно определять конструкторы
Даже несмотря на new, value type создастся на стеке!
Слайд 66Value types vs. reference types
Что делать, если я хочу завести
свой value type?
Ключевое слово struct
Слайд 67Value types vs. reference types
А зачем мне может понадобиться свой
value type?
Слайд 68Value types vs. reference types
А зачем мне может понадобиться свой
value type?
Экономия памяти:
Слайд 69Value types vs. reference types
А зачем мне может понадобиться свой
value type?
Экономия памяти:
sizeof(struct) = сумма всех полей
sizeof(class) = сумма всех
полей + 8 байт оверхеда
Слайд 70Value types vs. reference types
А зачем мне может понадобиться свой
value type?
Экономия памяти:
sizeof(struct) = сумма всех полей
sizeof(class) = сумма всех
полей + 8 байт оверхеда
Type object pointer (4 байта)
Sync block (4 байта)
Слайд 71Value types vs. reference types
А зачем мне может понадобиться свой
value type?
Экономия памяти:
sizeof(struct) = сумма всех полей
sizeof(class) = сумма всех
полей + 8 байт оверхеда
Снижение оверхеда на выделение памяти в куче
Слайд 72Boxing/unboxing
А может ли value type оказаться в куче?
Слайд 73Boxing/unboxing
А может ли value type оказаться в куче?
Был value type
— стал reference type?
Слайд 74Boxing/unboxing
Boxing — создание копии value-type объекта в куче
Unboxing — создание
на стеке value-type объекта, являющегося копией объекта из кучи
Слайд 75Boxing/unboxing
Почему это происходит?
Слайд 76Boxing/unboxing
Почему это происходит?
Список не содержит копии объектов, а только ссылки
Слайд 77Boxing/unboxing
Почему это происходит?
Список не содержит копии объектов, а только ссылки
Аргументом
служит object: выполняется семантика reference type
Слайд 78Boxing/unboxing
А теперь поподробнее
Слайд 80Boxing/unboxing
Чем чревато?
Boxing дорог: выделение памяти в куче
Слайд 81Boxing/unboxing
Чем чревато?
Boxing дорог: выделение памяти в куче
Unboxing дешевле (стековая память
уже выделена), но все равно не бесплатен: происходит копирование полей
Слайд 82Boxing/unboxing
Чем чревато?
Boxing дорог: выделение памяти в куче
Unboxing дешевле (стековая память
уже выделена), но все равно не бесплатен: происходит копирование полей
Как
избежать?
Слайд 83Boxing/unboxing: как избежать?
Правильные сигнатуры методов:
Слайд 84Boxing/unboxing: как избежать?
Типизованные коллекции
Слайд 85Value types vs. reference types
Коронные вопросы на собеседовании!
Чем отличаются value
types от reference types?
Какие value types вы знаете?
String — это
value type или reference type?
Что такое boxing/unboxing?
Слайд 90Getters and setters
Один из лучших примеров «синтаксического сахара» в C#
Слайд 92Getters and setters
Геттер и сеттер вызовутся при доступе к полю
Слайд 97Getters and setters
Настоятельная рекомендация: оборачивайте все поля геттерами/сеттерами!
Слайд 98Getters and setters
Настоятельная рекомендация: оборачивайте все поля геттерами/сеттерами!
Если уж совсем
лень — то есть простой способ:
Слайд 99Getters and setters
Настоятельная рекомендация: оборачивайте все поля геттерами/сеттерами!
Публичное поле без
геттера или сеттера — очень плохая практика
Слайд 101Getters and setters: а зачем?
Важный момент в терминологии:
Поле с геттером
или сеттером: property, свойство
Поле без геттера и без сеттера: field,
поле
Слайд 102Getters and setters: а зачем?
Рефлексия делает различие между полями (fields)
и свойствами (properties)
Как правило, динамический доступ по имени поля возможен
только до полей с геттерами/сеттерами
Слайд 104Итоги за сегодня
Пространства имен (namespaces) и ключевое слово static
Ссылки (references)
Reference
types и value types. Boxing и unboxing
Геттеры и сеттеры. Поля
(fields) и свойства (properties)
Слайд 105В следующей серии
ООП в C#. Почему наследоваться от двух интерфейсов
можно, а от двух классов — нет, и еще одна
ипостась слова new
Перегрузка операторов: почему вы сталкиваетесь с ней гораздо чаще, чем вам кажется
Оператор == и метод object.Equals()