Слайд 1.NET framework
Колотаев А.В.
Anton.Kolotaev@gmail.com
Слайд 2На этой лекции:
Элементарные типы
Значимые и ссылочные типы
Упаковка и распаковка значимых типов
Равенство
и тождество объектов
Видимость типов и членов
Константы
Поля
Слайд 3Элементарные типы
Элементарные типы – типы, которые поддерживаются компилятором напрямую и специальным
образом обрабатываются:
Целочисленные (8,16,32,64 разряда; со знаком и без)
С плавающей точкой (float, double, decimal)
String
Object
Char
Bool
Слайд 6Использование псевдонимов vs. имен типов FCL
Псевдонимы короче и читабельней
В разных языках
ключевому слову может соответствовать разные типы FCL: long в C# - это System.Int64, а в С++/CLI – System.Int32
В типах FCL есть методы, в именах которых используются имена типов FCL
Слайд 7Элементарные типы
Явное и неявное приведение между элементарными типами
Литеральная форма записи
Слайд 8Проверяемые и непроверяемые операции для элементарных типов
add/add.ovf; sub/sub.ovf; mul/mul.ovf; conv/conv.ovf
По умолчанию
проверка отключена.
Для ее включения на уровне файла есть ключ /checked+
Операторы checked и unchecked
Инструкции checked и unchecked
Слайд 9Ссылочные и значимые типы
В CLR тип определяет, каким образом его объекты
размещаются в памяти:
Объекты ссылочных (reference) типов размещаются только в управляемой куче и удаляются сборщиком мусора. Переменная ссылочного типа хранит указатель на объект, размещенный в куче
Объекты значимых (value) типов размещаются на стеке или как поля других типов. Экземплярные поля хранятся непосредственно в переменной
Слайд 10Ссылочные типы и производительность
Размещаются в управляемой куче
Содержат дополнительные поля: ссылка на
объект-тип и индекс SyncBlockIndex
Поля инициализируются нулем
Создание объекта может повлечь сборку мусора
Слайд 11Значимые типы
Определяются при помощи ключевого слова struct
Являются наследниками System.ValueType : System.Object
Не
могут иметь наследников
Могут реализовывать интерфейсы
Слайд 12Семантика копирования
Ссылочные типы: копируется только ссылка. Несколько переменных могут указывать на
один объект.
Значимые типы. Производится почленное копирование. Одному объекту соответствует ровно одна переменная
Слайд 13Значимые типы
Могут быть в упакованной (boxed) и неупакованной (unboxed) форме
Наследуются от
System.ValueType, который реализует правильно, но малоэффективно Equals и GetHashCode
Переменная значимого типа не может быть null’ом (хотя есть nullable типы)
Метод Finalize не вызывается
Желательно должны быть неизменяемыми
Слайд 14Размещение полей типа
Автоматический
Последовательный
Явный
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Auto)]
internal struct SomeValType {
Byte
b;
Int16 I;
}
Слайд 15Упаковка значимых типов
Требуется всегда, когда от значимого типа требуется поведение, описанное
в базовом классе или интерфейсе. Например, при вызове методов базового класса или приведении к базовому типу или интерфейсу
Распаковка – получение из упакованного объекта неупакованной его части.
public class boxed {
private T x;
public boxed(T x) { this.x = x; }
public override bool Equals(object o) {
return x.Equals(o);
}
public T unbox() { return x; }
// ….
}
Слайд 16Упаковка и производительность
Компилятор C# выполняет упаковку автоматически везде, где она требуется.
С другой стороны, она подразумевает создание объектов ссылочного типа и копирование в них полей значимого типа, что может ударить по производительности
Слайд 17Упаковка и производительность
public static void Main() {
Int32 v =
5;
Object o = v;
v = 123;
Console.WriteLine(v); // вызывается WriteLine(Int32)
Console.WriteLine(“, ”);
v = (Int32)o;
Console.WriteLine(v); // отображается 123, 5
}
Слайд 18Изменение полей в упакованных типах посредством интерфейсов
Слайд 19Изменение полей в упакованных типах посредством интерфейсов
Слайд 21Равенство объектов как оно должно быть
Слайд 22Сравнение объектов
Тождественность
Свойства сравнения
рефлексивность: x.Equals(x) == true
cимметричность: x.Equals(y) == y.Equals(x)
транзитивность: x.Equals(y) && y.Equals(z) ➔ x.Equals(z)
постоянство: если в сравниваемых значениях не произошло изменения, то результат сравнения должен остаться прежним
Слайд 23Сравнение объектов
System.IEquatable -- typesafe интерфейс для сравнения объектов типа T
Операторы ==
и !=
Интерфейсы IComparable и IComparable
Операторы <, >, <=, >=
Слайд 24Хеш-коды объектов
В System.Object есть метод GetHashCode. Его надо переопределить всегда, когда
переопределяется метод Equals
Принципы реализации GetHashCode:
-- равномерное распределение значений
-- максимальная скорость
-- должен основываться на неизменяемых полях объекта
-- x.Equals(y) ➔ x.GetHashCode() == y.GetHashCode()
Слайд 25Хеш-коды объектов
Реализация GetHashCode в System.Object возвращает id, уникальный для AppDomain’а.
Реализация GetHashCode
в System.ValueType использует рефлексию для того, чтобы сформировать хеш-код объекта, основываясь на значениях его полей
Слайд 26Члены типа
Константы
Поля
Конструкторы экземпляров
Конструктор типа
Методы
Перегруженные операторы
Операторы преобразования
Свойства
События
Вложенные типы
Слайд 27Видимость типов
Дружественные сборки
Слайд 28Видимость членов
Верификацию доступа к членам выполняет JIT-компилятор
При наследовании CLR позволяет повышать,
но не понижать уровень доступа к члену
Слайд 29Статические классы
Содержат только статические члены: поля, методы, свойства, события…
Нельзя создать экземпляр
статического класса
Является прямым потомком System.Object
Не может реализовывать никаких интерфейсов
Слайд 30Частичные классы
Могут быть определены в нескольких файлах одной сборки, используя ключевое
слово partial
Используются в первую очередь для отделения сгенерированной автоматически части класса от рукописной.
Слайд 31Ключевые слова, влияющие на отношения «базовый тип-наследник»
Слайд 32Константы
Идентификатор, который никогда не меняется
Может быть только элементарного типа
Кладется в метаданные
модуля, и при использовании ее значение встраивается в IL код (при изменении значения константы необходимо перекомпилировать модули ее использующие)
Нельзя получить адрес константы и передать ее по ссылке
Слайд 33Поля
Поле – это член данных, который хранит экземпляр value-типа или ссылку
на reference-тип
Статические неизменяемые поля можно использовать вместо констант, если хочется использовать неэлементарные типы и чтобы при изменении значения поля не приходилось перекомпилировать код, его использующий
Для изменения неизменяемого поля можно использовать рефлексию