C # как создавать функции, которые интерпретируются во время выполнения - PullRequest
6 голосов
/ 17 марта 2010

Я делаю Генетическую Программу, но нахожусь в ограничении с C #, где я хочу представить новые функции алгоритму, но я не могу сделать это без перекомпиляции программы. По сути, я хочу, чтобы пользователь программы предоставил разрешенные функции, и терапевт автоматически использует их. Было бы здорово, если бы пользователь знал как можно меньше о программировании.

Я хочу подключить новые функции, не компилируя их в программу. В Python это легко, так как все это интерпретируется, но я понятия не имею, как это сделать с C #. Кто-нибудь знает, как добиться этого в C #? Есть ли какие-нибудь библиотеки, методики и т. Д.?

Ответы [ 6 ]

13 голосов
/ 17 марта 2010

Это зависит от того, как вы хотите, чтобы пользователь программы «предоставлял разрешенные функции».

  • Если пользователь выбирает функции, которые вы уже реализовали, вы можете передавать их как делегаты или деревья выражений.
  • Если пользователь собирается написать свои собственные методы на C # или другом языке .NET и скомпилировать их в сборку, вы можете загрузить их с помощью Reflection.
  • Если вы хотите, чтобы пользователь мог вводить исходный код C # в вашу программу, вы можете скомпилировать его с помощью CodeDom, а затем вызвать получившуюся сборку с помощью Reflection.
  • Если вы хотите предоставить пользовательский язык выражений для пользователя, например, простой математический язык, затем (при условии, что вы можете проанализировать язык) вы можете использовать Reflection.Emit для генерации динамической сборки и вызывать ее, используя - как вы уже догадались - Reflection. Или вы можете построить дерево выражений из пользовательского кода и скомпилировать его с помощью LINQ - в зависимости от того, насколько вам нужна гибкость. (И если вы можете позволить себе подождать, деревья выражений в .NET 4.0 снимают многие из ограничений, которые были в 3.5, так что вы можете вообще избежать Reflection.Emit.)
  • Если вы рады, что пользователь вводит выражения с использованием Python, Ruby или другого языка DLR, вы можете разместить Dynamic Language Runtime, который будет интерпретировать код пользователя для вас.

Хостинг DLR (и IronPython или IronRuby) может быть хорошим выбором здесь, потому что вы получаете хорошо протестированную среду и все оптимизации, которые обеспечивает DLR. Вот инструкции по использованию IronPython.

Добавлено в ответ на ваш вопрос производительности: DLR достаточно умен в оптимизации. Он не слепо интерпретирует исходный код каждый раз: как только он преобразует исходный код (или, в частности, данную функцию или класс) в MSIL, он будет продолжать использовать это скомпилированное представление, пока исходный код не изменится (например, функция переопределена). Так что, если пользователь продолжает использовать одну и ту же функцию, но для разных наборов данных, то, пока вы можете хранить один и тот же ScriptScope, вы должны получить приличную производительность; То же самое, если вы беспокоитесь только о том, что во время генетического алгоритма вы будете выполнять одну и ту же функцию миллионы раз. Хостинг DLR довольно прост, поэтому не составит труда сделать подтверждение концепции и оценить, соответствует ли она вашим потребностям.

7 голосов
/ 17 марта 2010

Вы можете попытаться создать и манипулировать деревьями выражений . Используйте Linq для оценки деревьев выражений.

2 голосов
/ 17 марта 2010

Вы также можете использовать CodeDom для компиляции и запуска функции. Наверняка вы можете посмотреть в Google несколько примеров, которые могут соответствовать вашим потребностям. Кажется, эта статья «Как динамически компилировать код C #» и эта статья «Динамическое выполнение кода в .Net» может помочь вам.

1 голос
/ 17 марта 2010

На самом деле очень легко генерировать IL. Смотрите этот учебник: http://www.meta -alternative.net / calc.pdf

1 голос
/ 17 марта 2010

Вы можете взглянуть на System.Reflection.Emit для генерации кода на уровне IL.

Или сгенерируйте C #, скомпилируйте в библиотеку и загрузите ее динамически. Не так гибко.

1 голос
/ 17 марта 2010

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

Здесь

и

Здесь

Второй - это анализатор javascript, но его можно легко адаптировать.

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