【问题标题】:using CSharpCodeProvider to compile strings使用 CSharpCodeProvider 编译字符串
【发布时间】:2010-10-20 00:29:46
【问题描述】:

试图弄清楚如何利用 CSharpCodeProvider 在运行时编译字符串数据。

在 xml 中,我将相当于存储在字符串中的谓词条件。

我希望能够在当前上下文中执行并获得这些语句的结果。

例如当 <Condition>Value=="ABCD1234"</Condition> 被读取并执行,它应该在当前对象范围中查找值并根据语句的评估返回 truefalse

我认为我使用 CSharpCodeProvider 的方向是正确的,但是我能找到的所有示例都与编译为 .DLL 或 .EXE 相关,我真的只想在内存中编译,这样我就可以执行比较并返回 true或对应用程序的其他部分设置错误。

关于如何最好地解决这个问题的任何想法? CSharpCodeProvider 甚至是完成这项工作的最佳工具吗?

【问题讨论】:

  • “当前对象范围”是什么意思? CSharpCodeProvider 的结果将始终是一个程序集,这意味着您的“sn-p”必须存在于类中包含的方法中。因此,必须将“当前对象范围”作为您创建的封闭方法的参数自己进行检测。
  • 不知道我明白了,这是解释器和编译器之间的区别。当然,CodeDom 会让它更快很多。不是因为字符串。
  • 好吧,我只是想确保当我说Value="stuff" 时,值将是实例化对象的属性。
  • 是的,但是如果您要手动编写该类以在之后由 C# 编译,您如何在没有额外引用的情况下访问 Value 属性(例如 obj.Value)?在这种情况下你不能继承,所以你必须在你的类中编写同名属性,将调用委托给原始实例。

标签: c#


【解决方案1】:

我强烈建议使用FLEE 来处理类似的事情。它不了解原生 C#,但它能够解析和执行看起来适合您使用的合理函数子集。

我曾多次使用 FLEE,发现它易于使用且速度足够快。

【讨论】:

  • 我会玩这个。不过这让我思考。结果我忘记了我们在另一个项目中使用 Lex/YAAC。我会玩这个。谢谢。
【解决方案2】:

我个人宁愿创建一个小的 DSL(领域特定语言)而不是编译这样的字符串。问题是,将这些混合到一些编译的源代码中打开了注入攻击的大门,并且检查语法也很困难。为简单的表达式和谓词创建一个小型解析器实际上非常容易,因此如果您不依赖 LINQ 以及在您的条件下工作的任何东西,那么您可能会更好地使用 DSL 路由。

为了对我所说的内容有个印象,我邀请您看看我的 GOLD 解析器引擎,它是为这样的工作而设计的:http://code.google.com/p/bsn-goldparser/

解析过程的输出是语义 AST(抽象语法树),然后可以编写它以动态执行“解释”评估或创建 MSIL 代码,以便您获得快速编译( JITed) 代码以及完全控制正在发生的事情。

【讨论】:

    【解决方案3】:

    CSharpCodeProvider 可能有点矫枉过正。如果您的条件是基本的逻辑运算符(例如,等于、大于/小于),您最好构建一些委托并编写一个简单的解析器来执行条件。您的解析器将确定使用哪个运算符并执行适当的委托:

    delegate bool equalsDel(string s1, string s2)
    equalsDel = (s1, s2) => {return sq == s2;}
    //Get your strings from the file and invoke the delegate
    return equalsDel(s1, s2);
    

    查看访问者模式,了解如何编写解析器/访问者来确定运算符并执行适当的委托。您也许可以通过Func<T> 发挥创意,创建一个无需太多编码的高效系统。

    【讨论】:

    • 它们将是基本的逻辑操作,但我希望也能够利用大多数语言中固有的嵌套/分组。我想如果我走那条路,我只需要手写分组结构。
    • 如果您使用正确的解析器(例如,包含标记器的某些东西,然后使用定义明确的语法进行 LL/LALR 解析),您将“免费”获得。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多