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

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

        1. Создание объекта по его типу

При создании объекта вызывается его конструктор. Если разработчика устраивает вариант создания объекта с вызовом конструктора без аргументов (конструктора по умолчанию), то задача решается очень просто. Например, так:

class Class1

{ int n = 5;

static void Main()

{ string className = "App1.Class1";

Type type = Type.GetType(className);

Object data = Activator.CreateInstance(type);

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

Console.ReadLine();

}

}

Для варианта создания объекта с вызовом конструктора с аргументами предназначен специальный класс Activator. У него есть набор статических методовCreateInstance, с помощью которых можно создавать объекты, не только имея объектType, но также по имени сборки и имени класса, или по файлу сборки и имени класса. Среди методовCreateInstanceесть и такие, которые позволяют использовать конструкторы с аргументами и задавать пользовательские атрибуты создаваемого класса.

Примеры использования различных вариантов Activator.CreateInstance:

using System;

using System.Reflection;

using System.Diagnostics;

namespace ConsoleApplication2

{ class Class1

{ public static string DotNetFrameworkDir()

{ Assembly testAssy = Assembly.Load("mscorlib.dll");

return System.IO.Path.GetDirectoryName(testAssy.Location);

}

static void Main()

{ // создаём объект по имени сборки и имени класса

Object intObj = Activator.CreateInstance("mscorlib.dll"

, "System.Int32");

intObj = 5;

Console.WriteLine(Trace2.ObjectFields("intObj", intObj));

// создаём объект по файлу сборки и имени класса

Object rgn = Activator.CreateInstanceFrom(DotNetFrameworkDir()

+ "\\System.Drawing.dll"

, "System.Drawing.Region");

Console.WriteLine(Trace2.ObjectFields("rgn", rgn));

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

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

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

// Грузим сборку

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

Object rect = Activator.CreateInstance(assembly.FullName

, "System.Drawing.Rectangle"

, false // ignoreCase, учитывать регистр!

, 0, null // по умолчанию

, ctorArgs // вот они - параметры!

, null, null, null // всё остальное тоже по умолчанию

);

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

Console.ReadLine();

}

}

}

Примечание. Здесь применён простой способ получения пути к каталогу .NETFramework. Дело в том, что сборкаmscorlib.dllиспользуется в любой сборке, и потому всегда загружена. Остаётся только получить путь к папке, где лежит файл этой сборки, т.к. эта сборка всегда находится в каталоге .NETFramework.

Здесь приведён вариант создания объекта с использованием конструктора с параметрами. Составлен массив из параметров и передан в Activator.CreateInstance. Среди возможного множества конструкторов будет использован тот, который имеет в точности то же количество параметров и те же типы (и в том же порядке!), что и в переданном массиве параметров.

Примечание. Наряду с классомActivatorспособностью создавать объекты по их типу обладают классыAssembly,AppDomainи некоторые другие. У них тоже есть методыCreateInstance, работа с которыми ведётся подобным образом.