1: Основы типов
2: Все типы — производные от System. Object В CLR каждый объект прямо или косвенно является производным от System. Object. Это значит, что следующие определения типов идентичны: // Тип, неявно производный от Object class Employee . . . // Тип, явно производный от Object class Employee : System. Object . . .
3: Примитивные
5: C разрешает неявное приведение типа, если это преобразование «безопасно», то есть не сопряжено с потерей данных; пример — преобразование из Int32 в Int64. Int32 i 5; // Неявное приведение Int32 к Int32 Int64 l i; // Неявное приведение Int32 к Int64 Single s i; // Неявное приведение Int32 к Single Byte b (Byte) i; // Явное приведение Int32 к Byte Int16 v (Int16) s; // Явное приведение Single к Int16
6: Помимо приведения, компилятор «знает» и о другой особенности примитивных типов: к ним применима литеральная форма записи. Литералы сами по себе считаются экземплярами типа, поэтому можно вызывать экземплярные методы, например, следующим образом: Помимо приведения, компилятор «знает» и о другой особенности примитивных типов: к ним применима литеральная форма записи. Литералы сами по себе считаются экземплярами типа, поэтому можно вызывать экземплярные методы, например, следующим образом: Console. WriteLine(123. ToString() 456. ToString()); // "123456"
7: Ссылочные типы : память для ссылочных типов всегда выделяется из управляемой кучи; каждый объект, размещаемый в куче, содержит дополнительные члены, подлежащие инициализации; незанятые полезной информацией байты объекта обнуляются (это касается полей); размещение объекта в управляемой куче со временем инициирует сборку мусора.
8: Значимые типы : Экземпляры этих типов обычно размещаются в стеке потока В представляющей экземпляр переменной нет указателя на экземпляр; Поля экземпляра размещаются в самой переменной Поскольку переменная содержит поля экземпляра, то для работы с экземпляром не нужно выполнять разыменование (dereference) экземпляра Благодаря тому, что экземпляры значимых типов не обрабатываются уборщиком мусора, уменьшается интенсивность работы с управляемой кучей и сокращается количество сеансов уборки мусора, необходимых приложению на протяжении его существования.
9: Если тип называют классом (class), речь идет о ссылочном типе. Например, классы System. Object, System. Exception, System. IO. FileStream и System. Random — это ссылочные типы Если тип называют классом (class), речь идет о ссылочном типе. Например, классы System. Object, System. Exception, System. IO. FileStream и System. Random — это ссылочные типы
11: SomeVal v1 new SomeVal(); // Размещается в стеке SomeVal v1 new SomeVal(); // Размещается в стеке
12: // Две следующие строки компилируются, так как C считает, // Две следующие строки компилируются, так как C считает, // что поля в v1 инициализируются нулем SomeVal v1 new SomeVal(); Int32 a v1. x; // Следующие строки вызовут ошибку компиляции, поскольку C не считает, // что поля в v1 инициализируются нулем SomeVal v1; Int32 a v1. x; // error CS0170: Use of possibly unassigned field x // (ошибка CS0170: Используется поле x, которому не присвоено значение)
13: Важнейшие отличия между значимыми и ссылочными типы: Объекты значимого типа существуют в двух формах (см. следующий раздел): неупакованной (unboxed) и упакованной (boxed). Ссылочные типы бывают только в упакованной форме. Значимые типы являются производными от System. ValueType. Этот тип имеет те же методы, что и System. Object. Однако System. ValueType переопределяет метод Equals, который возвращает true, если значения полей в обоих объектах совпадают. Кроме того, в System. ValueType переопределен метод GetHashCode, который создает хеш-код по алгоритму, учитывающему значения полей экземпляра объекта. Из-за проблем с производительностью в реализации по умолчанию, определяя собственные значимые типы значений, надо переопределить и написать свою реализацию методов Equals и GetHashCode Поскольку в объявлении нового значимого или ссылочного типа нельзя указывать значимый тип в качестве базового класса, создавать в значимом типе новые виртуальные методы нельзя. Методы не могут быть абстрактными и неявно являются запечатанными (то есть их нельзя переопределить).
14: Переменные ссылочного типа содержат адреса объектов в куче. Когда переменная ссылочного типа создается, ей по умолчанию присваивается null, то есть в этот момент она не указывает на действительный объект. Попытка задействовать переменную с таким значением приведет к генерации исключения NullReferenceException. В то же время в переменной значимого типа всегда содержится некое значение соответствующего типа, а при инициализации всем членам этого типа присваивается 0. Поскольку переменная значимого типа не является указателем, при обращении к значимому типу исключение NullReferenceException возникнуть не может. CLR поддерживает понятие значимого типа особого вида, допускающего присваивание null Переменные ссылочного типа содержат адреса объектов в куче. Когда переменная ссылочного типа создается, ей по умолчанию присваивается null, то есть в этот момент она не указывает на действительный объект. Попытка задействовать переменную с таким значением приведет к генерации исключения NullReferenceException. В то же время в переменной значимого типа всегда содержится некое значение соответствующего типа, а при инициализации всем членам этого типа присваивается 0. Поскольку переменная значимого типа не является указателем, при обращении к значимому типу исключение NullReferenceException возникнуть не может. CLR поддерживает понятие значимого типа особого вида, допускающего присваивание null Когда переменной значимого типа присваивается другая переменная значимого типа, выполняется копирование всех ее полей. Когда переменной ссылочного типа присваивается переменная ссылочного типа, копируется только ее адрес. Вследствие сказанного в предыдущем пункте несколько переменных ссылочного типа могут ссылаться на один объект в куче, благодаря чему, работая с одной переменной, можно изменить объект, на который ссылается другая переменная. В то же время каждая переменная значимого типа имеет собственную копию данных «объекта», поэтому операции с одной переменной значимого типа не влияют на другую переменную. Так как неупакованные значимые типы не размещаются в куче, отведенная для них память освобождается сразу при возвращении управления методом, в котором описан экземпляр этого типа (в отличие от ожидания уборки мусора).