Курс лекций для студентов специальности i-31 03 04 Информатика всех форм обучения Минск 2010


Позднее связывание и кодогенерация



страница20/29
Дата09.08.2019
Размер0.64 Mb.
#126834
ТипКурс лекций
1   ...   16   17   18   19   20   21   22   23   ...   29

2.23. Позднее связывание и кодогенерация


Механизм отражения позволяет реализовать на платформе .NET позднее связывание (late binding). Этот термин обозначает процесс динамической загрузки типов при работе приложения, создание экземпляров типов и работу с элементами экземпляров.

Продемонстрируем позднее связывание на примере класса SimpleClass, размещённого в локальной сборке SimpleLibrary.dll.

namespace SimpleLibrary

{

public class SimpleClass



{

public SimpleClass() { }


public SimpleClass(int offset) { Offset = offset; }
public int Offset { get; set; }
public int Sum(int x) { return x + Offset; }

}

}



Первый этап позднего связывания – загрузка в память сборки с типом – выполняется при помощи метода Assembly.Load(). Для указания имени сборки можно использовать простую строку или объект класса AssemblyName.

AssemblyName assemblyName = new AssemblyName("SimpleLibrary");

// возможные исключения не обрабатываются!

Assembly assembly = Assembly.Load(assemblyName);

После загрузки сборки нужно создать объект требуемого типа. Для этого следует воспользоваться экземплярным методом Assembly.CreateInstance()1.

var typeName = "SimpleLibrary.SimpleClass";

// короткая версия

var o1 = (SimpleLibrary.SimpleClass)assembly.CreateInstance(typeName);

// полная версия, можно задать параметры конструктора (5-й аргумент)

var o2 = (SimpleLibrary.SimpleClass)assembly.CreateInstance(typeName,

false, BindingFlags.Default, null, new object[] {10},

CultureInfo.InvariantCulture, null);

В листинге, приведённом ниже, имя сборки, имя типа и метод объекта запрашиваются у пользователя в процессе выполнения программы.

Console.Write("Input assembly name: ");

Assembly assembly = Assembly.Load(Console.ReadLine());

Console.Write("Input full typename: ");

Type type = assembly.GetType(Console.ReadLine());

object obj = Activator.CreateInstance(type);

Console.Write("Input method name: ");

MethodInfo method = type.GetMethod(Console.ReadLine());

// создаём пустой массив для фактических параметров

var paramArray = new object[method.GetParameters().Length];

// вызываем метод, указывая целевой объект и набор аргументов

method.Invoke(obj, paramArray);

Платформа .NET имеет несколько средств, позволяющих выполнять различные виды кодогенерации, в частности, генерацию инструкций MSIL, генерацию деревьев исходного кода, обработку деревьев выражений.

Средства генерации инструкций промежуточного языка MSIL сосредоточены в пространстве имён System.Reflection.Emit. Данные средства востребованы, в основном, разработчиками компиляторов для платформы .NET.

Пространство имён System.CodeDom содержит типы для описания структуры документа с исходным кодом программы. Чтобы получить по такому документу листинг на выбранном языке программирования и скомпилировать его, нужны типы из пространства имён System.CodeDom.Compiler.

var compileUnit = new CodeCompileUnit(); // единица компиляции


// опишем пространство имён и свяжем его с единицей компиляции

var namespase = new CodeNamespace("SimpleLibrary");

namespase.Imports.Add(new CodeNamespaceImport("System"));

compileUnit.Namespaces.Add(namespase);


// опишем очень простой класс

var type = new CodeTypeDeclaration {

Name = "SimpleClass",

IsClass = true,

TypeAttributes = TypeAttributes.Public};

namespase.Types.Add(type);


// создадим элемент класса (поле Offset)

var field = new CodeMemberField {

Name = "Offset",

Type = new CodeTypeReference("System.Int32"),

Attributes = MemberAttributes.Public};

type.Members.Add(field);


// создадим исходник на языке C# и запишем его в файл

CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

using (var stream = new StreamWriter("SimpleClass.cs"))

{

provider.GenerateCodeFromCompileUnit(compileUnit, stream, null);



}

Деревья выражений описывают код в виде данных, которые хранятся в древовидной структуре. Каждый узел в дереве представляет выражение, например, вызов метода или бинарную операцию. Для хранения деревьев выражений служит класс System.Linq.Expressions.Expression.

Простейший способ создать дерево выражений в C# – использовать возможности компилятора, генерирующего деревья для лямбда-выражений:

Func lambda = n => n < 5; // обычная лямбда

Expression> tree = n => n < 5; // дерево

Пространство имен System.Linq.Expressions предоставляет программный интерфейс для создания деревьев выражений. Класс Expression содержит статические методы, которые создают узлы дерева выражений особых типов. Например, выражение ParameterExpression представляет именованный параметр, а выражение LoopExpression описывает цикл.

// построим вручную дерево выражений для лямбды n => n < 5

ParameterExpression n = Expression.Parameter(typeof(int), "n");

ConstantExpression five = Expression.Constant(5, typeof(int));

BinaryExpression nLessFive = Expression.LessThan(n, five);

Expression> tree =

Expression.Lambda>(nLessFive, new[] {n});

У созданного дерева выражений можно исследовать структуру, изменять элементы и компилировать его в инструкции MSIL:

Expression> tree = n => n < 5;
// декомпозиция дерева выражений

var param = tree.Parameters[0];

var op = (BinaryExpression) tree.Body;

var left = (ParameterExpression) op.Left;

var right = (ConstantExpression) op.Right;

Console.WriteLine("{0} => {1} {2} {3}",

param.Name, left.Name, op.NodeType, right.Value);
// компиляция дерева и вызов лямбды

Func lambda = tree.Compile();

Console.WriteLine(lambda(10));


Каталог: images
images -> В списке студентов (или магистрантов)
images -> Н. И. Сулейманов Комплект контрольно-оценочных средств для оценки результатов освоения профессионального модуля разработан на основе Федерального государственного образовательного стандарта среднего профессионального
images -> По направлению подготовки
images -> Добавить гаджеты. Добавление гаджетов
images -> Техническое задание № apnip/C. 2/CS/Ind/01 Международный консультант по улучшенной производительности орошаемого земледелия
images -> Комплект контрольно-оценочных средств по профессиональному модулю пм. 01 Техническое обслуживание и ремонт автотранспорта


Поделитесь с Вашими друзьями:
1   ...   16   17   18   19   20   21   22   23   ...   29




База данных защищена авторским правом ©vossta.ru 2022
обратиться к администрации

    Главная страница