C#Interpreter(无编译)

时间:2009-11-02 10:23:21

标签: c# scripting

那里有一个现成的C#解释器,那不依赖于运行时编译吗?

我的要求是:

  • 脚本引擎
  • 必须处理C#语法
  • 必须在中等信任环境中工作
  • 不得使用运行时编译(CodeDomProvider ...)
  • 开源(或至少免费用于个人和专业用途)

如果不清楚,我需要像Jint(http://jint.codeplex.com/)这样的东西,但它允许我编写C#脚本而不是JavaScript脚本。

感谢您的帮助。

12 个答案:

答案 0 :(得分:18)

你看过paxScript.NET吗?

答案 1 :(得分:12)

查看Mono项目。他们最近演示了CsharpRepl,听起来就像你追求的那样。 PDC 2008视频here

<小时/> 的更新
仔细看看似乎使用Mono.CSharp服务来评估脚本是不可能的。目前它与Mono运行时链接,并且它们不希望它在中等信任环境中运行。有关详细信息,请参阅this discussion

另一种可能性是在项目中包含Mono C# compiler(来源here)并使用它来生成从文件系统加载的程序集。您担心加载可能需要在单独的AppDomain中加载它们的所有程序集所需的资源。

答案 2 :(得分:5)

  

我需要评估10000+小   所有不同的脚本,   编译所有这些都只是   急剧下降

解释这些将会更加缓慢。我们遇到类似的问题,如下所示:

我们使用Gold Parser项目来解析源代码并将其转换为基于XML的“通用语言”。我们通过生成VB.Net源代码的转换来运行它(仅仅因为它不区分大小写)。然后,我们使用.Net运行时将它们编译为独立的DLL,并使用严格限制的访问来调用它。

听起来好像你正在创建类似动态网站的东西,人们可以在其中创建自定义模块或功能片段,但使用C#来实现这一点会带来几个主要问题;必须编译C#,唯一的办法就是在运行时插入它,这是不可行的,即使你编译每个代码片段,你也会得到10,000个DLL,这是不切实际的,也是无法使用的。

如果您的片段很少更改,那么我会考虑以编程方式将它们包装到一组源中,每个源都有一个唯一的名称,然后一次编译(或者每隔10分钟作为一个定时进程?)。这就是我们所做的,因为它还允许人们会话的“版本控制”,因此他们继续使用他们在会话开始时使用的DLL版本,但是当每个会话停止使用旧版本时,它就会被删除。

如果您的片段在一天中定期更改,那么我建议您查看一种解释过的脚本语言,甚至是PHP,并根据您需要的功能混合您的语言。诸如CScript和LinqPad之类的产品都使用CodeDomProvider,因为如果你想编译编译逻辑,你必须在某处安装IMSL。

唯一的另一个选择是编写自己的解释器并使用反射来访问您需要访问的所有其他库,但这非常复杂和可怕。

由于您的要求实际上无法实现,我建议您退后一步,找出消除一项或多项限制的方法。无论您是否找到FullTrust环境来编译您的代码段,都不需要完整的代码支持(即转移到解释的代码段支持),甚至将整个框架更改为非.Net的内容。

答案 3 :(得分:4)

LINQPad可以作为代码段IDE使用。该应用程序非常小巧轻便。它是免费的(如在啤酒中)但不是开源的。自动完成成本额外但不多(19美元)。

编辑:在仔细阅读本文中的评论后,我不认为LINQPad是你想要的。你需要能够以编程方式动态评估数千个小脚本的东西,对吧?我在工作中使用Iron Ruby非常容易。如果您愿意使用DLR语言,这可能会更可行。我也做了一些类似的工作,一些代码可以评估作为字符串传入的C#lambda表达式,但这是非常有限的。

答案 4 :(得分:4)

我编写了一个开源项目Dynamic Expresso,它可以将使用C#语法编写的文本表达式转换为委托(或表达式树)。表达式被解析并转换为Expression Trees而不使用编译或反射。

你可以这样写:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

var interpreter = new Interpreter()
                .SetVariable("service", new ServiceExample());

string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";

Lambda parsedExpression = interpreter.Parse(expression, 
                        new Parameter("x", typeof(int)));

parsedExpression.Invoke(5);

我的工作是基于Scott Gu的文章http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

答案 5 :(得分:3)

http://www.csscript.net/ 奥列格在code project

写了一篇很好的介绍

答案 6 :(得分:1)

它没有处理确切的C#语法,但是PowerShell与.NET框架很好地融合在一起并且是如此成熟的产品,我认为忽略它作为至少一种可能的解决方案是不明智的。微软推出的大多数服务器产品现在支持PowerShell用于其脚本界面,包括Microsoft Exchange和Microsoft SQL Server。

答案 7 :(得分:0)

我相信Mono有 mint ,他们是在为给定平台实现JIT之前使用的解释器。虽然官方网站上的文档(例如Runtime)说它只是在整合jitting VM之前的中间状态,但我很确定它是在我最后一次在Linux上编译时出现的。不幸的是,我现在还不能很好地检查它,但也许它正朝着你想要的方向发展。

答案 8 :(得分:0)

我遇到了同样的问题。在一个项目中,我希望提供一种通用的方法来指定控制何时必须生成某个字母的条件。在另一个项目中,条件是控制案例如何分配给队列。在这两个方面,以下解决方案都运行良好:

  1. 片段的语言 - 我选择了JScript,因此我不必担心变量类型。
  2. 编译 - 是的,它需要完全信任,但您可以将代码放在单独的程序集中并给予完全信任。不要忘记使用AllowPartiallyTrustedCaller属性标记它。
  3. 代码段数 - 我将每个代码段视为方法,而不是类。这样,多种方法可以组合成一个组件
  4. 磁盘使用情况 - 我在内存中进行了所有编译而未将程序集保存到磁盘。如果您需要重新加载它也会有所帮助。
  5. 所有这些都在生产中没有任何问题

    修改

    只是为了澄清'片段' - 我所说的条件只是布尔表达式。我以编程方式添加其他文本,将其转换为可编译类的方法和方法。

    我也可以用C#做​​同样的事情,尽管我仍然认为JScript更适合代码片段

    BTW我的代码是开源的browse随意。请记住,有很多代码与此讨论无关。如果您需要帮助来找到有关主题的部分,请告诉我

答案 9 :(得分:0)

蹦极#是你想要的东西,在短时间内,蹦极将是一个开源项目

  

http://www.crssoft.com/Services/Bungee

。您可以使用相同的c#syntaxt创建脚本。运行脚本时没有组件创建,解释是动态完成的,因此性能很高。所有关键字都可用,如c#。我希望你会非常喜欢..

答案 10 :(得分:0)

答案 11 :(得分:-1)

你要找Snippet Compiler什么?