Мы уже рассмотрели способ создания встраиваемого скриптового движка на основе CodeDom.Compiler и класса CSharpCodeProvider. Поставим теперь более амбициозную задачу, где не будем полагаться на готовый компилятор. Будем писать свой собственный генератор, который строит MSIL-код «на лету» и исполняет его.
Для начала, попробуем сложить два числа и распечатать результат как бы на C#, но не пользуясь его языковыми конструкциями:
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Type[] par = new Type[] { typeof(Int32), typeof(Int32) };
DynamicMethod func = new DynamicMethod("AddTwoValues", typeof(Int32), par, false);
ILGenerator il = func.GetILGenerator();
// это то же самое как: int AddTwoValues(int x, int y) { return x+y; }
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);
Object[] param = new Object[] { 13, 12 }; // готовим параметры 12 и 13
int iRet=(int)func.Invoke(null, param); // выполняем
// выводим что получилось
Console.WriteLine("{0}+{1}={2}", param[0], param[1], iRet);
}
}
}
using System;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Type[] par = new Type[] { typeof(Int32), typeof(Int32) };
DynamicMethod func = new DynamicMethod("AddTwoValues", typeof(Int32), par, false);
ILGenerator il = func.GetILGenerator();
MethodInfo fnWriteLine = typeof(Console).
GetMethod("WriteLine", new Type[] { typeof(Int32) });
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, fnWriteLine);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Call, fnWriteLine);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);
Object[] param = new Object[] { 13, 12 }; // готовим параметры 12 и 13
int iRet=(int)func.Invoke(null, param); // выполняем
// выводим что получилось
Console.WriteLine("{0}+{1}={2}", param[0], param[1], iRet);
}
}
}
ЕСЛИ КЛИЕНТ АКТИВЕН
НАЧАЛО БЛОКА
КУПИТЬ БИЛЕТ НА ПОЕЗД 120 на 31/12/2017 КУПЕЙНЫЙ НИЖНЕЕ
РАСПЕЧАТАТЬ БЛАНК
КОНЕЦ БЛОКА
К сожалению, не доступен сервер mySQL