Можно ли скомпилировать и выполнить новый код во время выполнения в .NET? - PullRequest
33 голосов
/ 24 октября 2008

Примечание. Оценка математических выражений не является целью данного вопроса. Я хочу скомпилировать и выполнить новый код во время выполнения в .NET. При этом ...

Я бы хотел, чтобы пользователь мог ввести любое уравнение, например, следующее, в текстовое поле:

x = x / 2 * 0.07914
x = x^2 / 5

И применить это уравнение к входящим точкам данных. Входящие точки данных представлены как x , и каждая точка данных обрабатывается по заданному пользователем уравнению. Я сделал это несколько лет назад, но мне не понравилось решение, потому что для каждого вычисления требовался анализ текста уравнения:

float ApplyEquation (string equation, float dataPoint)
{
    // parse the equation string and figure out how to do the math
    // lots of messy code here...
}

Когда вы обрабатываете множество точек данных, это вносит немало накладных расходов. Я хотел бы иметь возможность переводить уравнение в функцию на лету, чтобы ее можно было проанализировать только один раз. Это будет выглядеть примерно так:

FunctionPointer foo = ConvertEquationToCode(equation);
....
x = foo(x);  // I could then apply the equation to my incoming data like this

Функция ConvertEquationToCode будет анализировать уравнение и возвращать указатель на функцию, которая применяет соответствующую математику.

Приложение будет в основном писать новый код во время выполнения. Это возможно с .NET?

Ответы [ 15 ]

0 голосов
/ 04 февраля 2010

Вы можете реализовать калькулятор postfix stack . По сути, вам нужно преобразовать выражение в постфиксную нотацию, а затем просто перебрать токены в постфиксе для вычисления.

0 голосов
/ 04 февраля 2010

вы можете использовать system.CodeDom для генерации кода и его компиляции на лету посмотрите здесь

0 голосов
/ 17 декабря 2008

Я не знаю, возможно ли реализовать вашу функцию ConvertEquationToCode, однако вы можете сгенерировать структуру данных, которая представляет вычисление, которое вам нужно выполнить.

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

Имеет некоторые преимущества. Например, если вы выполняете анализ «что, если» и хотите изменить значение одного входа за раз, вы можете пересчитать результаты, которые зависят от значения, которое вы изменили, при этом сохраняя результаты, которые этого не делают.

0 голосов
/ 24 октября 2008

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

0 голосов
/ 24 октября 2008

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

...