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

Вызов конструкторов с параметрами, рассмотренный выше, является частным случаем динамического вызова методов. Вызов остальных методов производится без помощи дополнительных классов типа Activator. Этим занимается сам классType.

Динамический вызов метода динамически созданного объекта:

static void Main()

{ // Получаем объект-тип для System.Drawing.Rectangle

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

AssemblyName an = a.GetName();

Type typeRect = Type.GetType("System.Drawing.Rectangle,"

+ an.FullName, true);

// Готовим параметры для вызова конструктора

// Rectangle(Int32 x, Int32 y, Int32 width, Int32 height);

object[] ctorArgs = { 10, 10, 100, 100 };

Object rect = Activator.CreateInstance(typeRect, ctorArgs, null);

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

Console.WriteLine(Trace1.ObjectFields("rect", rect));

// Готовим параметры вызова метода Boolean Contains(Point pt);

System.Drawing.Point point = new System.Drawing.Point(50, 50);

object[] argContains = { point };

object contain = typeRect.InvokeMember("Contains"

, BindingFlags.Public

| BindingFlags.InvokeMethod

| BindingFlags.Instance

, null

, rect

, argContains

);

Console.WriteLine( contain.Equals(true) ?

"contains" : "does not contain");

Console.WriteLine(Trace1.ObjectFields("point", point));

Console.ReadLine();

}

Если вызываемый метод перегружен, будет вызван тот вариант метода, который имеет те же типы параметров, причем в том же порядке, что и типы элементов переданного массива параметров.

        1. Использование интерфейсов

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

Использование динамически созданного объекта через интерфейс:

static void Main()

{ // Получаем объект-тип для System.Drawing.SolidBrush

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

AssemblyName an = a.GetName();

Type typeBrush = Type.GetType("System.Drawing.SolidBrush,"

+ an.FullName, true);

// Готовим параметры для вызова конструктора

// SolidBrush(Color color);

object[] ctorArgs2 = { System.Drawing.Color.Blue };

Object brush = Activator.CreateInstance(typeBrush

, ctorArgs2, null);

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

Console.WriteLine(Trace1.ObjectFields("brush", brush));

// Получаем ссылку на интерфейс

ICloneable cloner = brush as ICloneable;

if (cloner != null)

{ Object brushCloned = cloner.Clone();

Console.WriteLine(Trace1.ObjectFields("brushCloned"

, brushCloned));

}

Console.ReadLine();

}

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

Для получения ссылки на интерфейс ICloneableздесь применяется операцияasязыка C#. Эта операция возвращает ссылку на интерфейс, если он реализован объектом. Если объект не поддерживает данный интерфейс, будет возвращенапустая ссылка(null). Ниже будут подробнее рассмотрены другие способы динамического приведения типов.