Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DiVM / OSISP / ОCиСП-Часть3 / Теория / Теория (ОСиСП).doc
Скачиваний:
29
Добавлен:
11.05.2015
Размер:
616.96 Кб
Скачать

Общее для Java и .Net.

Используется хранение метаданных в исполняемых модулях. Информация об используемых в программе типах данных. Это надо для:

  1. работы сборщика мусора

  2. обеспечения безопасности программ

  3. обеспечение высокоскоростной компиляции программ

Отличия метаданных .Net от метаданных Java: в Java нет непосредственного доступа к метаданным, а в .Net программист может использовать метаданные. Сами метаданные в .Net представлены в виде обычных объектов самой платформы (для С# метаданные представлены в виде объектов языка C#. Например, в базовом классе Object есть метод Object.Type( ), который возвращает объект, описывающий тип).

В Java есть простые и ссылочные типы данных. Свои простые типы создавать нельзя, а ссылочные – можно. В .Net есть ссылочные и размерные типы. Также есть простые типы, которые определены в самой платформе (ссылочный базовый тип – string). Программист сам может определять размерные типы данных.

Пример: модель того, что представляет собой физически объект в памяти.

Есть переменная Object o = new MyObject( );

Вся это структура относится к ссылочным типам данных.

На этапе компиляции в .Net программист может добавлять свои метаданные. Это достигается с помощью концепции “атрибуты” (custom attributes – пользовательские атрибуты). В C# и Delphi для добавления (создания) пользовательских атрибутов перед описанием класса, метода, какого-то типа данных указывается выражение в [ ]. Пример см. пользовательский атрибут [DllImport], приведенный выше в примере сборщика мусора:

[DllImport (“Kernel32.dll”)]

static extern bool CloseHandle (IntPtr p);

Атрибуты – это тоже объекты, которые укладываются в метаданные на этапе компиляции. DllImport – это по сути конструктор объектов.

Правила C# позволяют при указании параметров этого конструктора указывать их в позиционном формате (когда 2 параметра в методе – X и Y, то в X передается первый параметр, в Y – второй параметр). В VB – именованный формат:

Draw (int x, int y);

Draw (y=10, x=5);

Т.е. параметры можно менять местами.

Обычно, в других языках параметры атрибутов в именованном формате. В C# также можно использовать и именованный формат.

Для размерных типов данных:

Srtuct Point

{

int x;

int y;

};

При компиляции компилятор создает объект класса Point:

Point p=new Point ( );

Это можно графически для памяти показать так:

Привязка к типу обеспечивается статистически. О ней знает компилятор. Необходимости преобразования типов для размерных типов нет. Размерный тип не может содержать виртуальных методов. Поэтому наследоваться от него нельзя. Но единственное преобразование типа для размерных типов – это преобразование к базовому типу Object. Это преобразование к стандартному базовому типу называется boxing (упаковка). Существует возможность обратного преобразования – объекта класса Object к размерному типу (распаковка). Упаковка безопасна, распаковка – нет (если фактический тип объекта отличается от формального размерного типа, к которому производится преобразование, то будет ошибка преобразования типа).

Point p=new Point ( ); // создается физический объект на стеке, а не в

// динамической памяти

Object o=p; // о – объект ссылочного типа

Point p2 = (Point) o; // создается переменная p2, которой присваивается

// содержимое переменной о

p2.x=10;

p2.y=5;

В памяти происходит следующее:

Point [ ] array;

После строки Point p2 = (Point) o; создается объект ссылочного типа со значениями из 0. Присваивание ссылочному объекту размерочного – это создание нового объекта в динамической памяти.

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

Рекомендация: с объектами размерных типов надо работать как с целыми, надо избегать индивидуальной модификации полей и создания и вызова методов, которые могут изменять значения полей (например, изменять Pоint один на другой сразу, а не отдельно изменять поля).

Пусть есть структура:

Struct MyData

{

Pen pen; // ссылка на объект pen

void ReleasePen( )

{

pen.Dispose( );

pen = null; // метод

}

}

В программе объявлен динамический массив:

MyData [ ] array = new MyData [10];

foreach (MyData a in array)

{

a.Release( );

};

В памяти структура представляет следующее:

При прохождении массива каждый i-тый элемент копируется в а и далее вызывает ReleasePen, и ссылки из а на Pen будут удаляться (и объекты, на которые она указывает), а в массиве array ссылки остаются.

Надо избегать объявления в структурных типах полей ссылочного типа. В нашем примере лучше заменить слово struct на class (или заменить цикл foreach на for).