Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Динамическое создание перечислений




При динамическом создании перечисления мы действуем аналогично созданию классов. Только вместо класса TypeBuilder мы используем для создания перечисления класс EnumBuilder, в который потом добавляем нужные члены вместе с числовыми значениями.

 

using System;

using System.Reflection;

using System.Reflection.Emit;

 

// Создание имени сборки

AssemblyName an = new AssemblyName("MyAssembly");

an.Version = new Version("1.0.0.0");

 

// Создание сборки.

AssemblyBuilder ab;

ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save);

 

// Создание модуля в сборке

ModuleBuilder mb = ab.DefineDynamicModule("MyModule", "My.dll");

 

// Создание типа в сборке

EnumBuilder tb = mb.DefineEnum("MyColors", TypeAttributes.Public, typeof(int));

 

// Добавление членов в перечисление

tb.DefineLiteral("Red", 0);

tb.DefineLiteral("Pink", 1);

tb.DefineLiteral("Green", 2);

 

// Непосредственное создание типа

tb.CreateType();

 

// Сохранение типа в файл

ab.Save("My2.dll");

 

После выполнения этого кода в папке вашего проекта образуется файл My2.dll, внутри которого будет перечисление enum с именем MyColors, содержащий значения Red, Pink и Green.

2.2.7.4 Динамический "Hello World!"

Рассмотрим пример обучения программ программированию на примере классической программы "Hello World!".

Динамический вариант "Hello World!":

 

using System;

using System.Reflection;

using System.Reflection.Emit;

 

namespace DynHelloWorld

{ class Programmer

{ static public Type WriteCode()

{ AssemblyName assemblyName = new AssemblyName();

assemblyName.Name = "HelloWorldAssembly";

 

AssemblyBuilder assemblyBuilder =

AppDomain.CurrentDomain.DefineDynamicAssembly(

assemblyName, AssemblyBuilderAccess.Run);

 

ModuleBuilder moduleBuilder =

assemblyBuilder.DefineDynamicModule("HelloWorldModule");

 

TypeBuilder typeBuilder =

moduleBuilder.DefineType("HelloWorldClass"

, TypeAttributes.Public);

 

MethodBuilder methodBuilder =

typeBuilder.DefineMethod("HelloWorld"

, MethodAttributes.Public

, null, null);

 

ILGenerator il = methodBuilder.GetILGenerator();

 

// Генерируем код.

il.EmitWriteLine("Hello World!");

il.Emit(OpCodes.Ret);

 

return typeBuilder.CreateType();

}

}

 

class Class1

{ static void Main()

{ Type typeCode = Programmer.WriteCode();

object objCode = Activator.CreateInstance(typeCode);

MethodInfo methodInfo = typeCode.GetMethod("HelloWorld");

 

methodInfo.Invoke(objCode, null);

 

Console.ReadLine();

}

}

}

 

Класс-программист Programmer пишет код методом WriteCode(). Код – это метод класса HelloWorldClass, который содержится в модуле HelloWorldModule, который принадлежит сборке HelloWorldAssembly.

Класс-программист создаёт эти объекты с помощью набора соответствующих объектов-Buider'oв, прописанных в пространстве имён System. Reflection. Emit, попутно задавая атрибуты создаваемых объектов. В данном случае и тип и метод создаются как открытые (об этом говорят флаги TypeAttributes. Public и MethodAttributes. Public).

Самое интересное, конечно – это непосредственное генерирование кода. Он в данном случае состоит всего из двух команд языка IL: вывод строки на консоль и возврат из процедуры.

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

Но для этого надо обеспечить, чтобы сборка генерировалась при первой необходимости. О потребности в сборке можно узнать, перехватив событие AssemblyResolve класса AppDomain. Это событие генерируется при любой неудачной попытке загрузить в домен какую-либо сборку. А так как нашей сборки ещё нет (она ещё не сгенерирована), то любая попытка её загрузить будет неудачной.





Поделиться с друзьями:


Дата добавления: 2016-11-24; Мы поможем в написании ваших работ!; просмотров: 355 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Настоящая ответственность бывает только личной. © Фазиль Искандер
==> читать все изречения...

2363 - | 2084 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.008 с.