Финансы. Инструкция

  Все выпуски  

Уроки по C# и .NET. - Урок 72. Reflection - динамическое создание кода


Уроки по C#. Рассылки сайта progs.biz
Выпуск № 110
 
Начало > C# > Основы > Урок 72

Сахил Малик. Microsoft ADO.NET 2.0 для профессионалов
Сахил Малик. Microsoft ADO.NET 2.0 для профессионалов
Заказать на Озоне

Подробнее


Полные версии уроков (с картинками): урок 72.

Основы C#
Урок 72. Reflection - динамическое создание кода

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

Для начала небольшое замечание по порядку создания соответствующих объектов. Сначала мы должны сгенерировать сборку, затем на основании этой сборки - модуль, потом на основании этого модуля - тип (например, класс), потом на основании этого типа (класса) - его члены (конструкторы, методы и т. п.). И, уже в самом конце, мы создаем непосредственно сгенерированный на предыдущих шагах тип.

Вот пример такого кода:

            // Создание имени сборки.
            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");

            // Создание типа в сборке.
            TypeBuilder tb = mb.DefineType("MyClass", TypeAttributes.Public);

            // Создание конструктора без параметров.
            ConstructorBuilder cb0 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);

            // Добавление кода для конструктора.
            ILGenerator il0 = cb0.GetILGenerator();
            il0.Emit(OpCodes.Ret);

            // Создание конструктора с параметром типа string.
            ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public,
                CallingConventions.Standard, new Type[] { typeof(string)});
            // Добавление кода для конструктора.
            ILGenerator il = cb.GetILGenerator();
            il.EmitWriteLine("Constructor");
            il.Emit(OpCodes.Ret);

            // Непосредственное создание типа.
            tb.CreateType();

            // Сохранение типа в файл.
            ab.Save("qqq.dll");

Приведенный код при запуске создаст на жестком диске файл qqq.dll, в котором будет класс с 2-я конструкторами, причем второй конструктор будет при вызове выводить строчку "Constructor".

Несколько пояснений по коду.

Первое. Очень часто при создании типов и членов этих типов надо указать их атрибуты (модификаторы доступа типа public и т. п.). Это мы делаем через перечисления TypeAttributes и MethodAttributes, которое содержит соотвествующие значения (Public, например). Несколько необходимых значений из этих перечислений можно соединить через побитовое "или".

Второе. Метод Emit класса ILGenerator в качестве параметра принимает перечисление OpCodes, которое фактически содержит инструкции на языке IL - языке, который является аналогом для .NET обычного ассемблера. Это означает, что его инструкции не столь очевидны для реального программирования - именно поэтому в качестве примера таких IL-инструкций и была приведена самая простая из них - а именно выход из функции (OpCodes.Ret).

Рассылки сайта progs.biz
Visual C++, MFC
C# и .NET
VB.NET
ASP.NET
Win API
C/C++
Delphi
Java
HTML, PHP, mySQL, WEB-дизайн
Flash MX
C++ Builder
Ассемблер
SQL Server
DirectX
Обзор книг
Обзор программ
Новости сайта progs.biz


Parking.ru. Качественный виртуальный хостинг на платформе Windows(r): поддержка NET, многофункциональная панель управления, аренда бизнес-приложений, сертифицированные специалисты. Управляемый выделенный хостинг на платформе Windows(r): производительные серверы, профессиональная поддержка, аренда ПО Microsoft(r), безопасность, гарантии. http://www.parking.ru


Копирование любых материалов сайта без разрешения авторов и владельцев сайта запрещено.
© 2002-2007 сайт progs.biz
© 2002-2007 Игорь Алексеев

В избранное