Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторные работы Java и C# технологии.doc
Скачиваний:
171
Добавлен:
01.03.2016
Размер:
3.04 Mб
Скачать
        1. Получение экземпляра типа Type

Получить экземпляр класса Typeможно несколькими способами. Выбор способа зависит от условий задачи, и от того, какой информацией о типе вы располагаете при разработке программы (на момент компиляции).

1. Простейший случай получения экземпляра класса Type– когда тип определён в самой программе, или если при компиляции указана ссылка на сборку, содержащую данный тип. В этом случае экземпляр классаTypeможно получить посредством операцииTypeof(имя класса)

using System;

namespace App1

{ class Class1

{ static void Main()

{ Type type = typeof(Class1);

Console.WriteLine(type.FullName);

Console.ReadLine();

}

}

}

Следует подчеркнуть, что возможности среды .NET по работе с метаданными доступны из любого языка программирования, удовлетворяющего CLS (Common Language Specification). Поэтому всегда можно найти соответствующие конструкции в других языках среды .NET. Например, операцииTypeofязыка C# соответствуют операция __Typeofиз MSC++ или операторGetTypeиз VB.NET.

2. Если есть экземпляр интересующего вас класса, то соответствующий ему экземпляр класса Typeможно получить с помощью методаGetType. Все классы в среде .NET получают этот метод в наследство от классаObject.

Class1 app = new Class1();

Type type = app.GetType();

3. Имеется возможность перебрать все типы, определённые в сборке, и найти нужный класс по каким-либо критериям или выполнить необходимые действия со всеми классами в сборке. Вот так, например, можно напечатать имена всех типов, содержащихся в текущей сборке-приложении:

using System;

using System.Reflection;

namespace App1

{ class Class1

{ static void Main()

{ foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())

Console.WriteLine(type.Name);

Console.ReadLine();

}

}

}

В этом примере для получения текущей сборки-приложения использован статический метод GetExetutingAssemblyклассаAssembly, затем с помощью методаGetTypesполучен массив всех типов, содержащихся в текущей сборке.

Примечание. Следует обратить внимание на то, что в этом примере было использовано пространство имёнSystem.Reflection. Это главное вместилище классов и других типов, имеющих отношение к метаданным и рефлексии. Большинство типов, которые рассматриваются ниже, определены в этом пространстве имён. КлассType– исключение. Он настолько важен, что его описание помещено в пространство имёнSystem.

4. Возможна ситуация, когда во время написания программы тип объектов, с которыми предстоит работать, еще неизвестен. Он станет известен, только во время выполнения программы. Способ получения имени класса во время исполнения программы может быть самым разным. Например, вы запрашиваете его у пользователя, или считываете при старте программы из файла конфигурации. В этом случае указанием только имени типа не обойтись. Необходимо указать, в какой именно сборке содержится данный тип. Эту сборку потом необходимо загрузить динамически.

        1. Динамическая загрузка сборок

Приложение может загружать другие сборки из:

  1. Каталога приложения (private-сборки).

  2. Global Assembly Cache (GAC) (разделяемые сборки).

  3. Конкретного файла на диске.

Первые два способа идентифицируют сборку по имени.

Полное имя сборкисодержит, помимо собственно имени, также версию сборки, информацию олокализации(Culture) иоткрытый ключ сборки(PublicKeyToken). Вот пример имени сборки:

System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

Полное имя (т.е. содержащее все компоненты имени) однозначно идентифицирует сборку и по нему можно будет её загрузить.

Assembly asm = Assembly.Load("System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");

Имя сборки может быть как полным, так и частичным. Частичное имясборкипозволяет задействовать специальный механизм поддержания версий сборок. МетодLoadWithPartialNameклассаAssemblyзагружает сборку по частичной информации о ней.

Assembly asm = Assembly.LoadWithPartialName("System.Drawing");

В данном случае передано только имя сборки. В соответствии с политикой версий будет выбрана и загружена наиболее подходящая сборка. Этот способ более гибок, т.к. позволяет управлять загрузкой сборок, задавая или опуская различные параметры. Например, если вы укажете номер версии, то сборки другой версии (пусть даже более поздней!) использоваться не будут. А если явно задать локализацию (культуру), то в будущем не нужно беспокоиться, что приложение случайно подключит новую версию сборки, не поддерживающую указанную локализацию.

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

Assembly asm = Assembly.Load("MyAssembly"); // загрузка private-сборки

Функции Assembly.LoadиAssembly.LoadWithPartialNameпри выборе подходящей сборки первым делом просматривают каталог приложения, отдавая предпочтение private-сборкам.

Примечание: Размещение сборок в каталоге приложения считается предпочтительным. Такой способ помогает предотвратить взаимное влияние приложений – "кошмар DLL".

Динамическая загрузка сборки по полному пути к файлу позволяет загрузить любую сборку в системе (не только private- или изGAC).

Assembly a = Assembly.LoadFrom("D:\\WINNT\\Microsoft.NET\\Framework\\v1.0.3705\\System.Drawing.dll");

Однако этот способ недостаточно гибок и вряд ли стоит его широко применять.