- •Java и c# технологии прикладного програмирования
- •Java и c# технологии прикладного програмирования
- •Содержание
- •Введение
- •Лабораторная работа № 1 Коллекции c#
- •Цель работы
- •Теоретические сведения
- •Общие сведения о платформе .Net
- •Общие сведения о коллекциях c#
- •Обобщенные коллекции с#
- •Порядок выполнения лабораторной работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Получение информации о типе
- •Экземпляр типа Type
- •Получение экземпляра типа Type
- •Динамическая загрузка сборок
- •Динамическая загрузка типов
- •Исследование типа
- •Характеристики типа как целого
- •Члены класса
- •Динамическое создание объекта и вызов методов
- •Создание объекта по его типу
- •Динамический вызов методов
- •Использование интерфейсов
- •Позднее связывание
- •Динамическое приведение типов
- •Новые механизмы абстракции
- •Динамическое создание типов
- •Динамическое создание программного кода
- •Динамическое создание класса
- •Динамическое создание перечислений
- •Динамический "Hello World!"
- •Динамическое разворачивание циклов
- •Атрибуты
- •Атрибут это класс
- •Декларативное программирование
- •Код, выполняемый во время разработки
- •Использование атрибутов
- •Использование встроенных атрибутов
- •Определение и использование пользовательских атрибутов
- •Пример декларативного программирования
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Связный уровень взаимодействия ado.Net
- •Несвязный уровень взаимодействия ado.Net
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Связи между объектами в FluentNHibernate
- •Связь один к одному
- •Связь один ко многим
- •Связь многие ко многим
- •Способы выборки объектов в FluentNHibernate
- •Запросы NativeSql
- •Запросы по критерию
- •Запросы по образцу
- •Запросы hql
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Компиляция страниц по требованию
- •Страница asp.Net 2.0
- •Директива @Page
- •Жизненный цикл страницы
- •Новые свойства и методы объекта Page
- •Управление страницей
- •Установка выделения на элемент управления
- •Обновление данных без перезагрузки страницы
- •Отправка данных формы другой странице asp.Net
- •Шаблоны дизайна страниц
- •Создание шаблона дизайна
- •Создание страницы
- •Обработка шаблонов средой asp.Net
- •Использование разных шаблонов для разных браузеров
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Библиотеки модульного тестирования в .Net
- •Unit Testing Framework от Microsoft
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Контрольные вопросы
- •Рекомендованная литература
Динамическое создание перечислений
При динамическом создании перечисления мы действуем аналогично созданию классов. Только вместо класса 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.
Динамический "Hello World!"
Рассмотрим пример обучения программ программированию на примере классической программы "HelloWorld!".
Динамический вариант "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. Это событие генерируется при любой неудачной попытке загрузить в домен какую-либо сборку. А так как нашей сборки ещё нет (она ещё не сгенерирована), то любая попытка её загрузить будет неудачной.