Как я могу оценить код C # динамически? - PullRequest
84 голосов
/ 07 августа 2008

Я могу сделать eval("something()"); для динамического выполнения кода в JavaScript. Есть ли способ для меня сделать то же самое в C #?

Пример того, что я пытаюсь сделать: у меня есть целочисленная переменная (скажем, i), и у меня есть несколько свойств по именам: "Property1", "Property2", "Property3" и т. Д. Теперь я хочу выполнить некоторые операции со свойством «Свойство i » в зависимости от значения i.

Это действительно просто с Javascript. Есть ли способ сделать это с C #?

Ответы [ 16 ]

0 голосов
/ 02 мая 2018

Я пытался получить значение члена структуры (класса) по его имени. Структура не была динамичной. Все ответы не работали, пока я, наконец, не получил его:

public static object GetPropertyValue(object instance, string memberName)
{
    return instance.GetType().GetField(memberName).GetValue(instance);
}

Этот метод возвращает значение члена по его имени. Работает по регулярной структуре (классу).

0 голосов
/ 14 августа 2017

Я написал пакет SharpByte.Dynamic , чтобы упростить задачу динамической компиляции и выполнения кода. Код может быть вызван для любого объекта контекста с использованием методов расширения, как описано далее здесь .

Например,

someObject.Evaluate<int>("6 / {{{0}}}", 3))

возвращает 3;

someObject.Evaluate("this.ToString()"))

возвращает строковое представление объекта контекста;

someObject.Execute(@
"Console.WriteLine(""Hello, world!"");
Console.WriteLine(""This demonstrates running a simple script"");
");

запускает эти операторы как скрипт и т. Д.

Исполняемые файлы можно легко получить с помощью заводского метода, как показано в примере здесь - все, что вам нужно, это исходный код и список любых ожидаемых именованных параметров (токены встраиваются с использованием тройной скобки , например, {{{0}}}, чтобы избежать коллизий с string.Format (), а также синтаксисами, подобными Handlebars):

IExecutable executable = ExecutableFactory.Default.GetExecutable(executableType, sourceCode, parameterNames, addedNamespaces);

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

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

0 голосов
/ 05 ноября 2011

Использует отражение для анализа и оценки выражения привязки данных к объекту во время выполнения.

DataBinder.Eval Метод

0 голосов
/ 26 августа 2011

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

пример будет выглядеть так

TypeOf(Evaluate)
{
"1+1":2;
"1+2":3;
"1+3":5;
....
"2-5":-3;
"0+0":1
} 

и добавить его в список

List<string> results = new List<string>();
for() results.Add(result);

сохранить идентификатор и использовать его в коде

надеюсь, это поможет

0 голосов
/ 10 июня 2011

К сожалению, в C # нет встроенных средств для выполнения именно того, о чем вы просите.

Однако моя программа на C # eval позволяет оценивать код на C #. Он обеспечивает оценку кода C # во время выполнения и поддерживает множество операторов C #. На самом деле этот код можно использовать в любом проекте .NET, однако он ограничен использованием синтаксиса C #. Загляните на мой сайт, http://csharp -eval.com , для получения дополнительной информации.

0 голосов
/ 07 августа 2008

Вы можете сделать это с помощью функции-прототипа:

void something(int i, string P1) {
    something(i, P1, String.Empty);
}

void something(int i, string P1, string P2) {
    something(i, P1, P2, String.Empty);
}

void something(int i, string P1, string P2, string P3) {
    something(i, P1, P2, P3, String.Empty);
}

и так далее ...

...