- •Конспект лекций по курсу «Сети эвм» Часть 2 Сурков д.А.
- •Сравнительная характеристика технологий .Net и Java
- •Общее для Java и .Net.
- •Управление памятью в .Net
- •Процедурные типы данных (делегаты)
- •Динамические массивы
- •Многозадачность
- •1: Добавление в очередь ThreadPool нового делегата, который будет запускаться в отдельном потоке (из пула свободного потока). Делегат отработал – поток обратно в пул.
- •Исключительные ситуации
- •Шаблоны в с# (появились недавно в .Net 2.0)
- •В с# в шаблонах введено понятие итератора.
- •Массивы
- •Метод Get в SystemArray
- •Средства удалённого вызова .Net Remoting
- •Пользовательские атрибуты
- •Inherited – будем ли создавать атрибут для наследника.
- •Защищённые информационные системы. Технология “Эльбрус”
- •Защищенная файловая система
Общее для Java и .Net.
Используется хранение метаданных в исполняемых модулях. Информация об используемых в программе типах данных. Это надо для:
-
работы сборщика мусора
-
обеспечения безопасности программ
-
обеспечение высокоскоростной компиляции программ
Отличия метаданных .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).