4

我有一些公共的用户定义类,它们的成员之间有关系,还有一些具有特定和通用签名的方法。

我希望能够使用 if/then/else、foreach、do/while、变量赋值等基本控制语句来存储和操作这些类(加上 CLR 类)的自定义控制流。

自定义控制流应在运行时创建,然后存储以供以后使用和操作。这个想法是拥有控制流的数据表示,可能以抽象语法树的形式,具有强类型语法,以便能够应用遗传操作。生成的自定义代码必须作为另一个程序的一部分执行。

1)操作遗传操作的首选代码表示形式是什么,然后执行包括我的类在内的代码,

2) 对于上述问题,我应该使用哪些 c# 技术?我知道有相关技术,如反射、新的 c# 3.0 特性(lambda、表达式树)、CodeDom、DLR 库等,但哪种方法或组合最有效。

3)是否有这样的范例或实现可用?

编辑:该平台提供了定义的 c# 自定义类型的数据,包括常量和时间变量。

每时每刻都将规则应用于数据(基本条件或更复杂的功能),并决定采取一些行动。

我希望能够:

在树或图上表示规则并执行流程。

用户通过 UI 工具包创建自定义规则集

对树或图进行重新排列并应用 GP 操作

4

4 回答 4

2

反射是检查已经生成的类型、方法、字段等的技术,因此它现在可能对你没有多大帮助。

表达式树相当有趣,但是根据 AFAIK,它们不允许您创建复杂的程序流,因为 lambda 表达式不能有主体,这使得创建任何适度复杂的东西变得相当困难。

DLR 正在酝酿之中。您将获得一些零碎的信息,但只有下一个 .NET 版本将内置对 DLR 的支持。通过动态创建程序并执行它们,这可能是一个有趣的选择。

您现在可以做的可能是在动态方法或动态生成的程序集中发出 IL。您应该可以使用所有可能的构造,但随后的操作可能相当困难。

即便如此,有一个项目可以发挥相当多的 IL 魔法,甚至可能对您有用:LinFu。根据列表,您有一个 Dynamic Object 的实现,并且可以执行 dynamicObject.CreateDuck<InterfaceType>() 之类的操作

另一个可能有点繁重但也很有趣的路线是 WF(工作流基础)框架。这样的工作流应该可以由程序构建,并且由于它们的延续风格工作它们可能很有趣:您可以随时保持正在运行的工作流并在您离开的地方将其拾取。

在 WF 中,您应该可以使用所有传统的程序结构。

于 2009-02-27T13:12:57.597 回答
1

用 C# 等语言表示的育种程序非常棘手——它们根本就没有被设计成可延展的——你会发现你所做的绝大多数更改只会导致程序失败。

我会推荐两种替代方法之一:

  1. 伪机器语言,在两种 NOP 上使用模式匹配来允许分支或循环;
  2. 一种 LISP 链接语言,在命名函数上使用递归以允许迭代。

(1) 可以使用线性指令序列和某种形式的虚拟寄存器或堆栈机来表示。(2) 可以使用树表示,并使用某种形式的“减少”算法进行评估。

无论您使用哪种方法,您都需要在沙箱中执行程序 - 无限循环很常见,因此您需要能够在一定数量的循环后停止它们。

于 2009-02-27T13:11:18.270 回答
1

Dynamic Expression [example] API涵盖了这个领域的基础......

于 2009-02-27T13:13:27.143 回答
1

只需输出 c#(支持此功能的任何其他 .net 语言,f# 也可以很好地工作)并使用 CodeDomProvider 即时编译它。强制提供的代码为一个源文件,包括一种实现 IDynamicEntryPoint 的类型(使用静态方法或空构造函数作为入口点并将在构造后调用)

这应该是您开始的第一个呼叫端口,因为它可以快速尝试,同时长期具有最高性能的最佳机会(禁止动态 IL 输出,但即使那样您也可能无法击败编译器)

这显然有两个可能的缺陷,可能会破坏交易:

  • 生成的代码是一场安全噩梦,只应允许来自完全受信任的用户的代码输入。
  • 动态编译的代码在代码/接口更改方面很脆弱(代码必须包含的 dll 集可能会更改/可能不匹配)或 IDynamicEntryPoint 的签名可能会更改。

除非您对编写自己的语言/解析器/编译器感兴趣,否则请使用已经存在的。

于 2009-02-27T14:02:56.570 回答