Файл: 1_C#_Введение_в_программирование_Уч_пособ_(Марченко-2005).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 1391

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

i++;

}

}

}//======================================================================

}

Сборка. Класс Assembly

Класс Assembly определяет Сборку – основной строительный блок common language runtime приложения. Как строительный блок clr, сборка обладает следующими основными свойствами:

возможностью многократного применения,

versionable (версифицированностью),

самоописываемостью.

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

Сборки обеспечивают инфраструктуру, которая позволяет во время выполнения полностью “понимать” структуру и содержимое приложения, и контролировать версии и зависимости элеметнов выполняемого приложения.

Сборки бывают:

частными (private). Представляют наборы типов, которые могут быть использованы только теми приложениями, в состав которых они входят. Располагаются в файлах с расширениями .dll (.exe) и .pdb (program debug Database). Для того чтобы использовать в приложении частную сборку, её надо

ВКЛЮЧИТЬ в приложение, то есть, разместить в каталоге приложения (application directory) или в одном из его подкаталогов.

общего доступа (shared). Также набор типов и ресурсов внутри модулей (модуль

– двоичный файл сборки). Предназначены для использования НЕОГРАНИЧЕННЫМ количеством приложений на клиентском компе. Эти сборки устанавливаются не в каталог приложения, а в специальный каталог, называемый Глобальным Кэшем

Сборок (Global Assembly Cache - GAC). Этот каталог на платформе Windows XP

имеет путь C:\WINDOWS\assembly. Таким образом, в .NET ВСЕ совместно используемые сборки собираются в одном месте. Имя (“общее имя” или “строгое имя”) сборки общего доступа строится с использованием информации о версии

сборки.

сборка

строится

как

БИБЛИТОТЕКА

КЛАССОВ

(файл

с

Загружаемая

расширением .dll), либо как выполняемый модуль (файл с расширением .exe). Если это файл с расширением .dll, то в среде Visual Studio её использование

поддерживается специальными средствами среды. Это “полуавтоматическая” загрузка частной сборки в Reference приложения (Add Reference…). Сборки, располагаемые в .exe файлах, особой поддержкой для включения сборки не состав приложения не пользуется.

Для анализа сборки применяется утилита IlDasm.exe, которую можно подключить

кнепосредственно вызываемому из среды разработки VisualStudio списку утилит. Ниже представлены члены класса Сборки.

Открытые свойства

CodeBase

Возвращает

местонахождение

сборки,

указанное

 

первоначально, например, в объекте AssemblyName.

EntryPoint

Возвращает точку входа для этой сборки.

 

EscapedCodeBase

Возвращает URI, предоставляющий базовый код, включая

 

escape-знаки.

 

 

Evidence

Возвращает свидетельство для этой сборки.

 

FullName

Возвращает отображаемое имя сборки.

 

 

 

GlobalAssemblyCache

Возвращает значение, показывающее, была ли сборка

 

загружена из глобального кэша сборок.

 

ImageRuntimeVersion

Возвращает версию общеязыковой среды выполнения (CLR),

 

сохраненной в файле, содержащем манифест.

 

Location

Возвращает

местонахождение в

формате базового кода

 

загруженного файла, содержащего манифест, если для него

 

не было теневого копирования.

 

 

Открытые методы

 

 

 

 

109


CreateInstance

 

Перегружен. Находит тип в этой сборке и создает его

 

 

 

экземпляр, используя абстрактный метод.

 

 

 

CreateQualifiedName

 

Статический. Создает тип, задаваемый отображаемым

 

 

 

именем его сборки.

 

 

 

 

 

 

Equals

(унаследовано

от

Перегружен. Определяет, равны ли два экземпляра Object.

Object)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

GetAssembly

 

Статический. Возвращает сборку, в которой определяется

 

 

 

заданный класс.

 

 

 

 

 

 

GetCallingAssembly

 

Статический. Возвращает Assembly метода, который

 

 

 

вызывает текущий метод выполнения.

 

 

 

 

 

GetCustomAttributes

 

Перегружен. Возвращает пользовательские атрибуты для

 

 

 

этой сборки.

 

 

 

 

 

 

 

GetEntryAssembly

 

Статический. Возвращает процесс,

исполняемый

в

домене

 

 

 

приложения

по

умолчанию. В

других

доменах

приложений

 

 

 

это первый исполняемый процесс, который был выполнен

 

 

 

AppDomain.ExecuteAssembly.

 

 

 

 

 

 

GetExecutingAssembly

 

Статический.

Возвращает

Assembly,

из

которой

 

 

 

исполняется текущий код.

 

 

 

 

 

 

GetExportedTypes

 

Возвращает экспортируемые типы, определенные в этой

 

 

 

сборке.

 

 

 

 

 

 

 

 

GetFile

 

 

Возвращает объект FileStream для указанного файла из

 

 

 

таблицы файлов манифеста данной сборки.

 

 

 

GetFiles

 

 

Перегружен. Возвращает файлы в таблице файлов манифеста

 

 

 

сборки.

 

 

 

 

 

 

 

 

GetHashCode (унаследовано

от

Служит хеш-функцией для конкретного

типа,

пригоден для

Object)

 

 

использования в алгоритмах хеширования и структурах

 

 

 

данных, например в хеш-таблице.

 

 

 

 

 

GetLoadedModules

 

Перегружен.

 

Возвращает

все

загруженные

модули,

 

 

 

являющиеся частью этой сборки.

 

 

 

 

 

GetManifestResourceInfo

 

Возвращает информацию о способе сохранения данного

 

 

 

ресурса.

 

 

 

 

 

 

 

 

GetManifestResourceNames

 

Возвращает имена всех ресурсов в этой сборке.

 

 

 

 

 

GetManifestResourceStream

 

Перегружен. Загружает указанный ресурс манифеста из

 

 

 

сборки.

 

 

 

 

 

 

 

 

GetModule

 

 

Возвращает указанный модуль этой сборки.

 

 

 

GetModules

 

 

Перегружен. Возвращает все модули, являющиеся частью

 

 

 

этой сборки.

 

 

 

 

 

 

 

GetName

 

 

Перегружен. Возвращает AssemblyName для этой сборки.

 

 

 

GetObjectData

 

Возвращает сведения сериализации со всеми данными,

 

 

 

необходимыми для повторного создания этой сборки.

 

GetReferencedAssemblies

 

Возвращает объекты AssemblyName для всех сборок, на

 

 

 

которые ссылается данная сборка.

 

 

 

 

 

GetSatelliteAssembly

 

Перегружен. Возвращает сопутствующую сборку.

 

 

 

 

 

 

GetType

 

 

Перегружен. Возвращает объект Type, предоставляющий

 

 

 

указанный тип.

 

 

 

 

 

 

 

GetTypes

 

 

Возвращает типы, определенные в этой сборке.

 

 

 

 

 

 

IsDefined

 

 

Показывает, определен ли пользовательский атрибут,

 

 

 

заданный указанным значением Type.

 

 

 

 

 

Load

 

 

Статический. Перегружен. Загружает сборку.

 

 

 

 

 

 

 

LoadFile

 

 

Статический. Перегружен. Загружает содержимое файла

 

 

 

сборки.

 

 

 

 

 

 

 

 

LoadFrom

 

 

Статический. Перегружен. Загружает сборку.

 

 

 

 

 

 

 

LoadModule

 

 

Перегружен. Загружает внутренний модуль этой сборки.

LoadWithPartialName

 

Статический. Перегружен. Загружает

сборку

из

папки

 

 

 

приложения или из глобального кэша сборок, используя

 

 

 

частичное имя.

 

 

 

 

 

 

 

ToString

 

 

Переопределен. Возвращает полное имя сборки,

также

 

 

 

называемое отображаемым именем.

 

 

 

 

 

Открытые события

 

 

 

 

 

 

 

 

 

 

ModuleResolve

 

Возникает,

когда загрузчик

классов

общеязыковой

среды

 

 

 

выполнения не может обработать ссылку на внутренний

 

 

 

модуль сборки, используя обычные средства.

 

 

 

Защищенные методы

 

 

 

 

 

 

 

 

 

 

110



Finalize (унаследовано

от

Переопределен. Позволяет объекту

Object

попытаться

Object)

 

освободить ресурсы и выполнить

другие

завершающие

 

 

операции, перед тем как объект Object будет уничтожен в

 

 

процессе сборки мусора.

 

 

 

 

В языках C# и C++ для функций финализации используется

 

 

синтаксис деструктора.

 

 

MemberwiseClone

 

Создает неполную копию текущего Object.

 

(унаследовано от Object)

 

 

 

 

Класс сборки в действии

Исследование свойств и областей применения класса Assembly начинаем с создания тестовой однофайловой сборки AssemblyForStart в рамках проекта Class Library.

Первая сборка Operators00.exe:

using System; namespace Operators00

{

public class xPoint

{

float x, y; xPoint()

{

x = 0.0F; y = 0.0F;

}

public xPoint(float xKey, float yKey):this()

{

x = xKey; y = yKey;

}

public static bool operator true(xPoint xp)

{

if (xp.x != 0.0F && xp.y != 0.0F) return true; else return false;

}

public static bool operator false(xPoint xp)

{

if (xp.x == 0.0F || xp.y == 0.0F) return false; else return true;

}

public static xPoint operator | (xPoint key1, xPoint key2)

{

if (key1) return key1; if (key2) return key2; return new xPoint();

}

public static xPoint operator & (xPoint key1, xPoint key2)

{

if (key1 && key2) return new xPoint(1.0F, 1.0F); return new xPoint();

}

public void Hello()

{

Console.WriteLine(“Hello! Point {0},{1} is here!”,this.x,this.y);

}

}

class Class1

{

111


///<summary>

///The main entry Point for the application.

///</summary>

[STAThread]

static void Main() // У точки входа пустой список параметров. // Я пока не сумел ей передать через метод Invoke массива строк.

{

xPoint xp0 = new xPoint(1.0F, 1.0F); xPoint xp1 = new xPoint(1.0F, 1.0F);

if (xp0 || xp1) Console.WriteLine(“xp0 || xp1 is true!”); else Console.WriteLine(“xp0 || xp1 is false!”);

}

}

}

Вторая сборка AssemblyForStart.dll. В примере она так и не запускалась. Используется только для тестирования стандартных средств загрузки сборокбиблиотек классов.

using System;

namespace AssemblyForStart

{

///<summary>

///Class1 : первая компонента сборки AssemblyForStart.

///</summary>

public class Class1

{

public Class1()

{

Console.WriteLine(“This is constructor Class1()”);

}

public void fC1()

{

Console.WriteLine(“This is fC1()”);

}

}

}

А вот полигон AssemblyStarter.exe. В примере демонстрируется техника ПОЗДНЕГО СВЯЗЫВАНИЯ. Именно поэтому код, который выполняется после загрузки сборки не содержит в явном виде информации об используемых в приложении типах. Транслятор действует в строгом соответствии с синтаксисом языка C# и просто не поймёт пожелания “создать объект-представитель класса … который будет объявлен в сборке, которую предполагается загрузить в ходе выполнения приложения”.

using System;

using System.Reflection; using System.IO;

namespace AssemblyStarter

{

///<summary>

///Приложение обеспечивает запуск сборки.

///</summary>

class Class1

{

static void Main(string[] args)

{

//Сборка может быть вызвана непосредственно по имени

//(строковый литерал с дружественным именем сборки).

//Ничего особенного. Просто имя без всяких там расширений.

//Главная проблема заключается в том, сборки должны предварительно

112

//включаться в раздел References (Ссылки).

//Кроме того, информация о загружаемой сборке может быть представлена

//в виде объекта - представителя класса AssemblyName, ссылка на который

//также может быть передана в качестве аргумента методу Assembly.Load().

//Вот здесь как раз и происходит формирование этого самого объекта. AssemblyName asmName = new AssemblyName();

asmName.Name = “AssemblyForStart”;

//Версию подсмотрели в манифесте сборки с помощью IlDasm.exe.

Version v = new Version(“1.0.1790.25124”);

//Можно было бы для пущей крутизны кода поле Version проинициализировать

//непосредственно (дело хозяйское):

//asmName.Version = new Version(«1:0:1790:25124»);

asmName.Version = v;

//Ссылка на объект-представитель класса Assembly.

Assembly asm = null; try

{

//Загрузка сборки по «дружественному имени». //asm = Assembly.Load(«AssemblyForStart»);

//Путь и полное имя при загрузки частной сборки не имеют значения.

//Соответствующие файлы должны располагаться непосредственно в каталоге приложения. //asm = Assembly.Load //(@”D:\Users\WORK\Cs\AssemblyTest\AssemblyForStart\bin\Debug\AssemblyForStart.dll”); //asm = Assembly.Load(asmName);

//Если сборку организовать в виде исполняемого модуля и «запихнуть» в каталог

//вручную - загрузится и такая сборка.

asm = Assembly.Load(“Operators00”);

}

catch(FileNotFoundException e)

{

Console.WriteLine(“We have a problem:” + e.Message);

}

//Итак, решено. Загрузили сборку, содержащую объявление класса xPoint.

//Если сборка загрузилась - с ней надо что-то делать. Ясное дело,

//надо выполнять программный код сборки.

//Первый вариант выполнения. В сборке содержатся объявления двух классов:

//класса xPoint и класса Class1. Мы воспользуемся объявлением класса xPoint,

//построим соответствующий объект-представитель этого класса, после чего

//будем вызывать нестатические методы-члены этого класса.

//Всё происходит в режиме ПОЗДНЕГО связывания. Поэтому ни о каких ЯВНЫХ упоминаниях

//имён типов не может быть речи. Единственное явное упоминание - это упоминание

//имени метода.

object[] ps = {25,25};

Type[] types = asm.GetTypes();

// Здесь используется класс Activator!

object obj = Activator.CreateInstance(types[0],ps);

MethodInfo mi = types[0].GetMethod(“Hello”); mi.Invoke(obj,null);

//Второй вариант выполнения. Воспользуемся тем обстоятельством, что загружаемая

//сборка не является библиотекой классов, а является обычной выполнимой сборкой

//с явным образом обозначенной точкой входа - СТАТИЧЕСКОЙ функцией Main(), которая

//является членом класса Class1.

mi = asm.EntryPoint;

//Вот всё получилось! Единственное, что я не сделал, так это не смог передать

//в точку входа загруженной сборки массива строк-параметров

//(смотреть на точку входа данной сборки).

//Ну не удалось. Потому и в сборке Operators точку сборки объявил без параметров. mi.Invoke(null,null);

}

}

}

Собрали, запустили. Получилось. Стало быть, ВСЁ ХОРОШО. В ходе выполнения приложения класс Assembly позволяет:

113