Net framework 5, а также среды Visual Studio 2012 и C#



Download 6,27 Mb.
Pdf ko'rish
bet112/658
Sana12.06.2023
Hajmi6,27 Mb.
#950840
1   ...   108   109   110   111   112   113   114   115   ...   658
Bog'liq
CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C


Глава.5 .Примитивные,.ссылочные.и.значимые.типы
private readonly Int16 m_x;
...

Атрибут 
StructLayoutAttribute
также позволяет явно задать смещение для 
всех полей, передав в конструктор 
LayoutKind.Explicit
. Затем можно применить 
атрибут 
System.Runtime.InteropServices.FieldOffsetAttribute
ко всем полям 
путем передачи конструктору этого атрибута значения типа 
Int32
, определяющего 
смещение (в байтах) первого байта поля от начала экземпляра. Явное размещение 
обычно используется для имитации того, что в неуправляемом коде на C/C++ 
называлось 
объединением
(union), то есть размещения нескольких полей с одного 
смещения в памяти, например:
using System;
using System.Runtime.InteropServices; 
// Разработчик явно задает порядок полей в значимом типе
[StructLayout(LayoutKind.Explicit)] 
internal struct SomeValType { 
[FieldOffset(0)] 
private readonly Byte m_b; // Поля m_b и m_x перекрываются 
[FieldOffset(0)] 
private readonly Int16 m_x; // в экземплярах этого класса

Не допускается определение типа, в котором перекрываются ссылочный и значи-
мый типы. Можно определить тип, в котором перекрываются несколько значимых 
типов, однако все перекрывающиеся байты должны быть доступны через открытые 
поля, чтобы обеспечить верификацию типа.
Упаковка и распаковка значимых типов
Значимые типы «легче» ссылочных: для них не нужно выделять память в управ-
ляемой куче, их не затрагивает сборка мусора, к ним нельзя обратиться через 
указатель. Однако часто требуется получать ссылку на экземпляр значимого типа, 
например если вы хотите сохранить структуры 
Point
в объекте типа 
ArrayList
(определен в пространстве имен 
System.Collections
). В коде это выглядит при-
мерно следующим образом:
// Объявляем значимый тип
struct Point { 
public Int32 x, y; 

public sealed class Program { 
public static void Main() { 


157
Упаковка.и.распаковка.значимых.типов
ArrayList a = new ArrayList(); 
Point p; // Выделяется память для Point (не в куче) 
for (Int32 i = 0; i < 10; i++) { 
p.x = p.y = i; // Инициализация членов в нашем значимом типе
a.Add(p); // Упаковка значимого типа и добавление 
// ссылки в ArrayList

... 


В каждой итерации цикла инициализируются поля значимого типа 
Point
, после 
чего 
Point
помещается в 
ArrayList
. Задумаемся, что же помещается в 
ArrayList

сама структура 
Point
, адрес структуры 
Point
или что-то иное? За ответом обратимся 
к методу 
Add
типа 
ArrayList
и посмотрим описание его параметра. В данном случае 
прототип метода 
Add
выглядит следующим образом:
public virtual Int32 Add(Object value); 
Отсюда видно, что в параметре 
Add
должен передаваться тип 
Object
, то есть 
ссылка (или указатель) на объект в управляемой куче. Однако в примере я передаю 
переменную 
p
, имеющую значимый тип 
Point
. Чтобы код работал, нужно преобразо-
вать значимый тип 
Point
в объект из управляемой кучи и получить на него ссылку.
Для преобразования значимого типа в ссылочный служит 
упаковка
(boxing). 
При упаковке экземпляра значимого типа происходит следующее.
1. В управляемой куче выделяется память. Ее объем определяется длиной значи-
мого типа и двумя дополнительными членами — указателем на типовой объект 
и индексом блока синхронизации. Эти члены необходимы для всех объектов 
в управляемой куче.
2. Поля значимого типа копируются в память, только что выделенную в куче.
3. Возвращается адрес объекта. Этот адрес является ссылкой на объект, то есть 
значимый тип превращается в ссылочный.
Компилятор C# создает IL-код, необходимый для упаковки экземпляра значи-
мого типа, автоматически, но вы должны понимать, что происходит «за кулисами» 
и помнить об опасности «распухания» кода и снижения производительности.
В предыдущем примере компилятор C# обнаружил, что методу, требующему 
ссылочный тип, в параметре передается значимый тип, и автоматически создал код 
для упаковки объекта. Вследствие этого поля экземпляра 
p
значимого типа 
Point
в период выполнения копируются во вновь созданный в куче объект 
Point
. Полу-
ченный адрес упакованного объекта 
Point
(теперь это ссылочный тип) передается 
методу 
Add
. Объект 
Point
остается в куче до очередной уборки мусора. Перемен-
ную 
p
значимого типа 
Point
можно использовать повторно, так как 
ArrayList
ничего 
о ней не знает. Заметьте: время жизни упакованного значимого типа превышает 
время жизни неупакованного значимого типа.



Download 6,27 Mb.

Do'stlaringiz bilan baham:
1   ...   108   109   110   111   112   113   114   115   ...   658




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish