среда, 14 августа 2013 г.

[recovery mode] Ссылочные и значимые типы данных в CLR via C# (часть 1)

Ссылочные и значимые типы.




CLR поддерживает две разновидности типов: ссылочные (reference types) и значимые

(value types). Помимо этих есть еще и примитивые типы(но я их опишу в следующих статьях).

Большинство типов в FCL(Framework Class Library)- ссылочные, но программисты чаще всего используют значимые. В чем между ними разница спросите вы?

Переменные ссылочного типа содержат в себе ссылки на фактические данные и при этом ссылка указывает на определенную область в памяти, которая была выделена при создании такой переменной. Память же выделяется при этом в управляемой куче — это область памяти, в которой размещаются управляемые объекты и работает сборщик мусора. Так как С# это полностью управляемый язык, то одной из его главных особенностей то, что в процессе работы программы он все время контролирует расход ресурсов и все объекты, которые он создает(если они уже не нужны и не используются) сборщик мусора уничтожает. То есть контроль над расходом ресурсов автоматизирован, при этом в неуправляемой куче за освобождением памяти от ненужных объектов следит сам программист, что усложняет написание задачи.


У переменной значимого типа поля экземпляра размещаются в самой переменной. Поле представляет собой изменяемое или неизменяемое значение. Поле может быть статическим и является частью ТИПА, или же быть экземплярным(нестатическим) и являться частью самого ОБЪЕКТА. Чтобы наиболее полностью понять разницу между объектом и типом, нужно хорошо разбираться в концепциях ООП. Также в отличие от ссылочного типа, память для значимого типа выделяется при этом в стеке потока. Стек потока — это область памяти, которая используется для передачи параметров в методы и хранения определенных в пределах методов локальных переменных. Те, кто может быть знаком с многопоточным выполнением программ, то такой поток еще по-другому называют «Стек пользовательского режима». Его размер всегда равен 1Мб. Чтобы вы правильно поняли, то метод static void Main() это и есть главный поток программы, в котором мы создаем значимые переменные, а также методы с параметрами и без параметров. А ведь эти переменные и параметры надо где-то хранить, вот для этого и используется стек потока.


Так в чем же состоит существенная разница между этими двумя типами. Все кроется в том, как выделяется память для этих двух типов. Как выше было сказано, в одном случае память выделяется в куче, в другом случае в стеке. Так вот, если все типы были бы ссылочными, то скорость работы программы очень резко бы упала. Ведь представьте, что при каждом обращении к типу Int32, то сколько бы раз нужно было бы выделять память в куче при создании переменной. Поэтому для ускорения работы, CLR предлагает нам «облегченные» — значимые типы. В такой переменной нет указателя на экземпляр, поля экземпляра размещаются в самой переменной. При этом переменные не обрабатываются сборщиком мусора. А также момент размещения в стеке достаточно быстр. Предположим мы создаем переменную Int32 — это 32-разрядное значение и среда знает уже изначально, сколько нужно выделить памяти для этой переменной, поэтому выделение происходит моментально.


К ссылочным типам относятся:


  • class

  • interface

  • delegate

  • object

  • string


Значимые типы:


  1. Структуры (struct)

  2. Перечисления (enum)


Структуры делятся на следующие категории:



  • Числовые типы:



  1. Целочисленные типы (sbyte, byte,char,short,ushort,int,uint,long,ulong)

  2. Типы с плавающей точкой (float,double)

  3. decimal (обозначает 128-разрядный тип данных. По сравнению с типом данных с плавающей запятой, тип decimal имеет более точный и узкий диапазон, благодаря чему он походит для финансовых расчетов.)



  • bool (для хранения логических значений, true и false)

  • Пользовательские структуры


Как известно корнем иерархии всех типов, классов и т.д. является класс Object. По умолчанию он всегда явлется базовым классом. В документации .NET Framework сказано, что структуры являются прямыми потомками типа System.ValueType, который является производным в свою очередь от System.Object, при этом метод Equels возвращает true, если значения полей у обоих объектов совпадают. Так же алгоритм метода GetHashCode реализован с учетом значений полей. Но при создании своего значимого типа рекомендуется переопределить оба этих метода. При этом значимые типы являются изолированными в целях безопасности. Поэтому при создании своего собственного значимого типа нельзя в качестве базового указывать другие типы, например Boolean, Char, Int32 и так далее.


В следующей статье я опишу как правильно подобрать тип в зависимости от поставленных задач, а также будет рассматриваться упаковка и распаковка значимых типов.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends: 'You Say What You Like, Because They Like What You Say' - http://www.medialens.org/index.php/alerts/alert-archive/alerts-2013/731-you-say-what-you-like-because-they-like-what-you-say.html


Комментариев нет:

Отправить комментарий