Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Учебное пособие 1082

.pdf
Скачиваний:
3
Добавлен:
30.04.2022
Размер:
753.13 Кб
Скачать

{

using System; using Shapes;

public class ShapeUser

{

static void Main()

{

Circle c = new Circle(1.0F); Console.WriteLine("Площадь круга (1.0) равна {0}",

c.Area());

}

}

}

Добавить в проект ссылку на shapes.dll.

Изменить в ShapesUser ссылку на ссылку на модуль moreshapes.dll. С помощью ildasm проследите за изменениями в файле shapes.dll.

Создать клиента для moreshapes.dll, который будет использовать объекты Circle, Triangle, Square. Изучить его свойства с помощью ildasm.

Вывести список командных опций утилиты gacutil,

изучить их.

КОНТРОЛЬНЫЕ ВОПРОСЫ

1.Что такое сборка?

2.Из чего состоит сборка?

3. Как посмотреть содержимое сборки?

4.Какая утилита просматривает заголовки сборки?

5.Что представляет собой манифест сборки?

6.Что такое метаданные сборки?

СОДЕРЖАНИЕ И ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ

Изучить теоретический материал, ответить на контрольные вопросы. Разработать приложения по представленному заданию. Составить отчёт.

9

РАБОТА № 2

РЕФЛЕКСИЯ

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

ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

Основные классы

Рефлексия – средство получения сведений о типе дан-

ных.

Рефлексия выявляет типы данных, становящиеся известными во время выполнения приложения [1, 4]. Для применения рефлексии подключается пространство имен

System.Reflection.

Класс Туре – основной класс, производный от абстрактного класса System.Reflection.MemberInfo.

В классе MemberInfo определены свойства, доступные только для чтения (табл. 1).

 

Таблица 1

 

 

Свойство

Описание

Type

Тип класса или интерфейса, в котором объяв-

DeclaringType

ляется отражаемый член

MemberTypes

Тип члена. Это значение показывает, являет-

MemberType

ся ли член полем, методом, свойством, собы-

 

тием или конструктором (перечисление)

int

Значение, связанное c конкретными метадан-

MetadataToken

ными

Module Module

Объект типа Module, представляющий мо-

 

дуль (исполняемый файл), в котором нахо-

 

дится отражаемый тип

string Name

Имя типа

Type

Тип отражаемого объекта

ReflectedType

 

 

10

Свойство MemberType возвращает тип MemberTypes -

перечисление, в котором определяются значения, обозначающие различные типы членов:

MemberTypes.Constructor,

MemberTypes.Method,

MemberTypes.Field,

MemberTypes.Event.

MemberTypes.Property.

Часто используемые методы класса Туре представлены в табл. 2.

 

Таблица 2

 

 

Метод

Описание

ConstructorInfо[]

Получает список конструкторов для задан-

GetConstructors()

ного типа

EventInfо[]

Получает список событий для заданного ти-

GetEvents()

па

FieldInfо[]

Получает список полей для заданного типа

GetFields()

 

MemberInfо[]

Получает список членов для заданного типа

GetMembers()

 

MethodInfо[]

Получает список методов для заданного ти-

GetMethods()

па

PropertyInfо[]

Получает список свойств для заданного типа

GetProperties ()

 

Класс MethodInfo является производным от абстрактного класса MethodBase, который наследует от класса MemberInfo, т.е. можно пользоваться членами, определенными в этих классах.

Получить методы класса можно с помощью метода

MethodInfo[] GetMethods().

Для хранения имени метода служит свойство Name. GetParameters() возвращает список параметров анализи-

руемого метода:

11

ParameterInfо[] GetParameters().

В классе ParameterInfо определены свойства: Name – строка, содержащая имя параметра, ParameterType – тип параметра, инкапсулирован в объекте класса Туре.

Существует форма метода GetMethods(), фильтрующая извлекаемые сведения о методах.

Фильтры задаются с помощью специальных флагов.

MethodInfo[] GetMethods(BindingFlags <флаги>).

BindingFlags – перечисление, заданное следующими значениями.

DeclaredOnly – извлекаются методы, которые определены в классе. Унаследованные методы не включаются.

Instance – извлекаются методы экземпляра. Nonpublic – извлекаются не отрытые методы. Public – извлекаются открытые методы. Static – извлекаются статические методы.

Флаги комбинируются операцией ИЛИ. Instance или Static следует указывать вместе с флажком Public или Nonpublic. В противном случае сведения о методах не будут извлечены.

Далее методы можно вызывать методом Invoke() из класса MethodInfo

object Invoke(object obj, object[] parameters),

где obj обозначает ссылку на объект, для которого вызывается метод.

Для вызова статических методов параметру obj передается нулевая ссылка (null).

Любые аргументы метода указываются в массиве parameters.

Если аргументов нет, то вместо parameters указывается

null.

Количество элементов массива parameters должно точно соответствовать количеству передаваемых аргументов.

12

Возвращаемое методом значение передается методу Invoke(), который его же и возвращает.

Конструкторы извлекаются при вызове GetConstructors() для объекта Туре.

Наиболее часто используемый формат

ConstructorInfо[] GetConstructors().

GetConstructors() возвращает массив объектов класса ConstructorInfо, описывающих конструкторы.

Класс ConstructorInfo – наследник абстрактного класса MethodBase, который наследует от класса MemberInfо.

В классе есть собственный метод GetConstructors(), возвращающий список параметров конструктора.

Метод действует как и GetParameters() из класса

MethodInfо.

Для создания объекта заданного типа вызывается

Invoke() из класса ConstructorInfo

object Invoke(object[] parameters).

После выполнения метод Invoke() возвращает ссылку на сконструированный объект.

Извлечение сведений о сборке

Во время выполнения программы можно получить сведения о внешней сборке. Для этого создается объект класса

Assembly.

В Assembly открытый конструктор не определяется. Объект класса Assembly получается при вызове одного

из его методов.

Загружает сборку по заданному её имени метод

LoadFrom():

static Assembly LoadFrom(string <файлCборки>),

где <файлCборки> – имя файла сборки.

После получения объекта класса Assembly можно извлечь определённые в нём типы, вызвав метод GetTypes():

Туре[] GetTypes().

13

Метод возвращает массив типов, содержащихся в сбор-

ке.

Рефлексия позволяет не знать о методах заранее.

Все сведения для конструирования объекта и вызовов его методов берутся из сборки динамически.

ЗАДАНИЕ

1. Создать новый проект.

В проект необходимо включить 1 или несколько классов, каждый из которых содержит конструкторы, поля и методы. Простейший пример приведён ниже.

class MyClass

{

int x; int y;

public MyClass(int x, int y)

{this.x = x; this.y = y; } public int Sum()

{return x+y; }

public bool IsBetween(int i)

{

if(x < i && i < y) return true;

else

return false;

}

public void Set(int a, int b)

{

x = a; y = b;

}

public void Set(double a, double b)

{

x = (int) a; у = (int) b;

}

public void Show()

14

{

Console.WriteLine(" x: {0}, y: {1}", x, y);

}

}

Создать клиентский класс ReflectionDemo, определяющий в процессе выполнения программы имя класса его поля и методы. Например:

class ReflectDemo

{

static void Main()

{

Type t = typeof(MyClass);

//получить объект класса Type, представляющий класс

MyClass

Сonsole.WriteLine("Анализ методов, определенных " + "в классе " + t.Name);

Console.WriteLine() ; Console.WriteLine("Поддерживаемые методы: "); MethodInfo[] mi = t.GetMethods();

//вывести методы, поддерживаемые в классе MyClass

foreach(Methodlnfo m in mi)

{

// вывести возвращаемый тип и имя каждого метода

Console.Write(" " + m.ReturnType.Name +

" " + m.Name +"(");

// вывести параметры

ParameterInfo[] pi = m.GetParameters() ; for (int i=0; i < pi.Length; i++) { Console.Write(pi[i].ParameterType.Name +

" " + pi[i].Name);

if(i+1 < pi.Length) Console.Write(", ");

}

Console.WriteLine(")");

Console.WriteLine();

}

}

15

}

Выполнить проект, проверить правильность результатов.

2.Добавить в созданные классы новые конструкторы и методы.

Например, в MyClass добавить ещё 1 конструктор (заполнение полей случайными числами) и метод Mult(), вычисляющий произведение полей. Выполнить проект, проверить правильность результатов.

3.Изменить код класса ReflectDemo так, чтобы не выво-

дились данные о методах Object.

4.Вызвать методы класса, например, MyClass c помо-

щью Invoke().

5.С помощью метода Invoke() создать экземпляр класса. Например, экземпляр класса MyClass с помощью 3-го (добавленного самостоятельно) конструктора.

6.Добавить новый класс в проект. Например, к классу

MyClass добавить новый класс AnotherClass

class AnotherClass

 

 

{

 

 

 

string msg;

 

 

public AnotherClass(string str)

 

{

msg = str;

}

 

public void Show()

 

 

{

Console.WriteLine(msg);

}

}

 

 

 

7.Из разработанных классов построить библиотеку.

Например, построить из классов библиотеку MyClasses.dll.

8.Программно извлечь сведения о сборке – созданной библиотеке, например, о MyClasses.dll. Проверить полученные результаты с помощью утилиты ildasm.

16

КОНТРОЛЬНЫЕ ВОПРОСЫ

1.Что такое рефлексия?

2.Для чего используется рефлексия?

3.Какие классы используются в рефлексии?

СОДЕРЖАНИЕ И ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ

Ознакомиться с теоретическими сведениями, ответить на контрольные вопросы. По заданию разработать приложение, использующее рефлексию, составить отчёт.

17

РАБОТА № 3

ДИНАМИЧЕСКОЕ СОЗДАНИЕ ОБЪЕКТОВ

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

ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

Извлечение сведений о полях, свойствах, интерфейсах

Метод GetFields() возвращает поля для заданного типа: FieldInfo [ ] fi = t.GetFields();

В примере метод ListFields() извлекает поля и выводит имена каждого из полей по LINQ-запросу [1, 3].

// Отображение имён полей типа static void ListFields(Type t)

{

Console.WriteLine ("***** Поля*****");

Fieldlnfo [ ] fi = t.GetFields();

var fieldNames = from f in t.GetFields() select f.Name; foreach (var name in fieldNames)

Console.WriteLine ("->{0}", name); Console.WriteLine ();

}

Метод GetProperties() возвращает свойства для заданного

типа

PropertyInfo [ ] pi = t.GetProperties();

В примере метод ListProps() выводит имена свойств типа

t.

// Отображение имён свойств типа static void ListProps(Type t)

{

18