Файл: 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