2010-03-16 2 views
6

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

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

+2

это не совсем ответит на ваш вопрос, но поскольку вы используете .net, вы можете использовать F # для этой части вашего приложения, поскольку его можно интерпретировать во время выполнения. – andy

ответ

13

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

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

Хостинг DLR (и IronPython или IronRuby) может быть хорошим выбором здесь, потому что вы получаете хорошо протестированную среду и все оптимизации, предоставляемые DLR.Here's a how-to using IronPython.

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

+0

Мне нравятся варианты отражения, которые вы упомянули ... они могут быть моим лучшим вариантом. DLR может быть хорошей альтернативой, есть ли значительная служебная нагрузка при вызове метода DLR? Методы будут вызваны ОЧЕНЬ часто, поэтому я хотел бы использовать опцию, которая имеет как можно меньше накладных расходов. – Kiril

+0

Я добавил некоторую информацию о том, как DLR улучшает производительность с помощью повторяющегося кода. Однако у меня нет количественных показателей, но вы можете найти что-то в Google или не получив достаточно простого для размещения DLR и быстро перейдя. – itowlson

+0

Я не планирую изменять исходный код во время выполнения, вероятно, это будет тот же метод, но с другим экземпляром данных, поэтому DLR может быть хорошей альтернативой. Я также собираюсь использовать memoization, поэтому, если одни и те же параметры всегда дают одинаковые результаты, тогда метод не будет бесполезно выполнен. Благодаря :). – Kiril

7

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

+2

. Деревья выражений лучше, чем чистая функция eval. –

+0

Мой GP имеет несколько человек, и каждый человек имеет дерево функций и констант. Узел в дереве может быть функцией или константой ... означает ли это, что я должен заменить функцию на данном узле деревом выражений? Как пользователь может подключить их функцию? – Kiril

+0

Обратите внимание, что дерево действительно не содержит функцию, а перечисление, которое идентифицирует функцию. Когда вызываемый «исполнитель» просто смотрит на перечисление и вызывает соответствующую функцию. – Kiril

1

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

Here

и

Here

второй является Java-оценщик, но может быть адаптировано достаточно легко.

1

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

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

2

Вы также можете использовать CodeDom для компиляции и запуска функции. Уверен, что вы можете google увидеть некоторые примеры, которые могут соответствовать вашим потребностям. Кажется, что this article "How to dynamically compile C# code" и this article "Dynamically executing code in .Net" могут вам помочь.

 Смежные вопросы

  • Нет связанных вопросов^_^