6

我正在制作一个遗传程序,但我遇到了 C# 的限制,我想向算法展示新功能,但如果不重新编译程序就无法做到。本质上,我希望程序的用户提供允许的功能,GP 会自动使用它们。如果要求用户尽可能少地了解编程,那就太好了。

我想插入新功能而不将它们编译到程序中。在 Python 中这很容易,因为它都是解释的,但我不知道如何用 C# 来做。有人知道如何在 C# 中实现这一点吗?是否有任何库、技术等?

4

6 回答 6

13

这取决于您希望程序的用户如何“提供允许的功能”。

  • 如果用户正在选择您已经实现的函数,您可以将它们作为委托或表达式树传递。
  • 如果用户打算用 C# 或其他 .NET 语言编写自己的方法,并将它们编译成程序集,则可以使用反射加载它们。
  • 如果您希望用户能够在您的程序中键入 C# 源代码,您可以使用 CodeDom 对其进行编译,然后使用 Reflection 调用生成的程序集。
  • 如果您想为用户提供自定义表达式语言,例如简单的数学语言,那么(假设您可以解析语言)您可以使用 Reflection.Emit 来生成动态程序集并使用 - 你猜对了 -反射。或者,您可以从用户代码构建表达式树并使用 LINQ 进行编译——这取决于您需要多大的灵活性。(如果您等得起,.NET 4.0 中的表达式树消除了 3.5 中的许多限制,因此您可以完全避免 Reflection.Emit。)
  • 如果您对用户使用 Python、Ruby 或其他 DLR 语言输入表达式感到满意,您可以托管动态语言运行时,它将为您解释用户的代码。

在这里托管 DLR(以及 IronPython 或 IronRuby)可能是一个不错的选择,因为您可以获得经过良好测试的环境以及 DLR 提供的所有优化。 这是使用 IronPython 的方法。

针对您的性能问题添加: DLR 在优化方面相当聪明。它不会每次都盲目地重新解释源代码:一旦将源代码(或者,特别是给定的函数或类)转换为 MSIL,它将继续重用该编译表示,直到源代码更改(例如函数被重新定义)。因此,如果用户继续使用相同的功能但在不同的数据集上,那么只要您可以保持相同的 ScriptScope,您应该会获得不错的性能;如果您担心的是您将在遗传算法期间运行相同的函数无数次,则同上。托管 DLR 非常容易,因此进行概念验证和衡量以查看它是否符合您的需求应该不难。

于 2010-03-16T23:27:15.180 回答
7

您可以尝试创建和操作表达式树。使用Linq评估表达式树。

于 2010-03-16T23:23:09.650 回答
2

您还可以使用 CodeDom 编译和运行函数。当然,您可以通过 google 查看一些可能适合您需求的示例。看来这篇文章“如何动态编译 C# 代码”这篇文章“在 .Net 中动态执行代码”可以帮助你。

于 2010-03-16T23:34:42.350 回答
1

您可以从代码中访问编译器,然后可以创建已编译代码的实例并使用它们而无需重新启动应用程序。周围有它的例子

这里

这里

第二个是 javascript 评估器,但可以很容易地适应。

于 2010-03-16T23:25:17.297 回答
1

您可以查看 System.Reflection.Emit 以在 IL 级别生成代码。

或者生成 C#,编译成库并动态加载。几乎没有那么灵活。

于 2010-03-16T23:25:53.210 回答
1

实际上,生成 IL 非常容易。请参阅本教程:http ://www.meta-alternative.net/calc.pdf

于 2010-03-16T23:46:34.300 回答