Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Динамическое .Net программирование для тех, кому некогда

Anna | 17.06.2014 | нет комментариев
Инфраструктура .Net содержит встроенные средства генерирования кода (On-the-Fly Code Generation). Это разрешает .Net-программе в момент своего исполнения самосильно (без участия программиста) скомпилировать текст, написанный на каком-либо языке программирования и выполнить получившийся код. Разумно было бы ждать, что для осуществления этих действий в стандартной .Net-библиотеке предусмотрен примитивный способ соответствующего класса. Но к сожалению это не так. Microsoft, проделав большой путь по встраиванию в среду .Net средств генерирования кода, не сделала самый конечный шаг насупротив простейшим надобностям программистов. Значит, придётся сделать данный шаг самосильно.

Самое примитивное средство предлагаемое Microsoft для решения описанной задачи — это класс CSharpCodeProvider, тот, что входит в стандартную библиотеку .Net. Применение этого класса — не дюже трудная задача, но тем не менее было бы благотворно иметь инструмент, превращающий применение сгенерированного на лету кода в задачу банальную.

В итоге получился маленький комплект классов, центральным из которых являетсяTech.DynamicCoding.CodeGenerator. Начнем его изложение с простейшего примера применения. (Тексты библиотеки и примеров есть в архиве).

Примитивный динамический код

Представим, вам необходимо вычислить значение числового выражения, заданного в текстовом виде. Скажем, вот такого «12345678 * 9 9». В этом случае вам довольно написать следующее:

var result = CodeGenerator.ExecuteCode<int>("return 12345678 * 9   9;");

Cначала вы формируете фрагмент C#-кода и передаёте его как параметр вызова способаCodeGenerator.ExecuteCode<T>. Тип возвращаемого кодом значения вы задаёте как параметр-тип способа. Это всё, что вам нужно сделать в этом простейшем случае. Так легко? Задача решена?

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

На самом деле не всё так легко. Дабы рассмотреть «подводные камни», нужно заглянуть «под капот» способаExecuteCode. Дело в том, что данный способ формирует начальный код временной сборки, компилирует её, загружает в память нынешнего процесса, позже чего исполняет. Задача состоит в том, что если вам потребуется вычислить схожее выражение с другими числовыми значениями, то каждая эта последовательность действий будет проделана снова, правда код получится одинаковый. Дело не только в том, что на это будут потрачено время, но ещё и в том, что в память будет загружена вторая, фактически равная первой сборка.

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

    var result = CodeGenerator.ExecuteCode<double>("return a * b   c;", 
        CodeParameter.Create("a", 9876543.21), 
        CodeParameter.Create("b", 9),
        CodeParameter.Create("c", -0.01));

    var result2 = CodeGenerator.ExecuteCode<double>("return a * b   c;",
        CodeParameter.Create("a", 12345678.9),
        CodeParameter.Create("b", 8),
        CodeParameter.Create("c", 0.9));

В этом варианте, мы задали формулу отдельно, а значения параметров отдельно. Способ ExecuteCode проверяет, нет ли среди ранее скомпилированных им сборок, подходящей для выполнения нынешнего вызова. Если начальный C#-код, возвращаемый им тип, а также типы и имена параметров совпадают, то дозволено применять приготовленную при первом вызове ExecuteCode сборку вторично.

Повторное применение динамического кода

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

    var code = CodeGenerator.CreateCode<DateTime>(
        "return StartDate.AddDays(Duration);",
        new CodeParameter("StartDate", typeof(DateTime)),
        new CodeParameter("Duration",  typeof(int)));

    var result1 = code.Execute(DateTime.Parse("2013-01-01"), 256);
    var result2 = code.Execute(DateTime.Parse("2013-10-13"), 131);

Этапы приготовления кода и его исполнения тут разнесены во времени. На первом этапе задается начальный текст фрагмента C#-кода, тип возвращаемого значения, имена и типы параметров. На втором этапе готовый к исполнению код вызыв

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB