简体   繁体   English

在.NET 4中编译.NET代码?

[英]Compiling .NET code in .NET 4?

I remember when .NET 4 was in beta there was a video of a developer that made a command-line app that he could type C# code into and it would compile the code on the fly. 我记得当.NET 4处于测试版时,有一个开发人员的视频制作了一个命令行应用程序,他可以输入C#代码,它会动态编译代码。 The idea was that the compiler was now available in the .NET language. 我们的想法是编译器现在可以在.NET语言中使用。

Anyone recall where this is? 有谁记得这是什么? I need to create an application with a small macro language and I would love to use C# as that macro language, but I don't know where to find this library.. 我需要用一个小的宏语言创建一个应用程序,我很乐意使用C#作为那种宏语言,但我不知道在哪里找到这个库..

You can use the CSharpCodeProvider class to compile assemblies at runtime. 您可以使用CSharpCodeProvider在运行时编译程序集。

You'll need to make a boilerplate template to wrap the macro commands in a static method in a class. 您需要创建一个样板模板,将宏命令包装在类中的静态方法中。

For example: 例如:

static readonly Assembly[] References = new[] { typeof(Enumerable).Assembly, typeof(Component).Assembly };
public Action CompileMacro(string source) {
    var options = new CompilerParameters(References.Select(a => a.Location).ToArray()) {
        GenerateInMemory = true
    };
    string fullSource = @"public static class MacroHolder { public static void Execute() { \r\n" + source + "\r\n} }";
    try {
        var compiler = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });

        var results = compiler.CompileAssemblyFromSource(options, fullSource);

        if (results.Errors.Count > 0)
            throw new InvalidOperationException(String.Join(
                Environment.NewLine, 
                results.Errors.Cast<CompilerError>().Select(ce => ce.ErrorText)
            ));

        return (Action)Delegate.CreateDelegate(
            typeof(Action),
            results.CompiledAssembly.GetType("MacroHolder").GetMethod("Execute")
        );
    } finally { options.TempFiles.Delete(); }
}

Not sure where the one you're referring to is anymore, but what you're talking about is an Interactive Shell. 不确定你所指的那个在哪里,但你所说的是一个Interactive Shell。

The only one I recall seeing is the CSharpRepl which was released by the Mono team. 我记得唯一看到的是由Mono团队发布的CSharpRepl CSharpRepl also contains the Compiler As a Service functionality that the Mono team developed. CSharpRepl还包含Mono团队开发的“编译器即服务”功能。

您可以尝试使用CS-Script作为替代方案 - 允许您运行单独的C#文件,就像它们是脚本文件一样。

If you're open to other suggestions, you can use Python or F# or Boo as a macro language today. 如果您对其他建议持开放态度,可以使用Python或F#或Boo作为宏语言。

I prefer Python, myself; 我更喜欢Python,我自己; it's one of the best-designed languages. 它是设计最好的语言之一。 C# has borrowed heavily from Python in its later developments (iterator blocks, lambdas, ...). C#在后来的开发中借用了Python(迭代器块,lambdas,......)。

Manning Publications has a book called IronPython in Action ; Manning Publications有一本名为IronPython in Action的书; chapter 15 is all about using IronPython in other programs (as a scripting engine, or as plugins). 第15章是关于在其他程序中使用IronPython(作为脚本引擎或插件)。

Maybe you mean CodePad.NET ? 也许你的意思是CodePad.NET Well, it's not a command-line app but it is open-source and might point you in the right direction. 好吧,它不是一个命令行应用程序,但它是开源的,可能会指向正确的方向。

I wouldn't go Python, it doesn't have the .NET infrastructure, therefore you are limited. 我不会去Python,它没有.NET基础设施,因此你是有限的。

F# is amazing. F#太神奇了。

The Compiler-as-a-Service feature has been available in Mono for quite some time and there are signs that it might appear in .NET 5 or 6, but it's not available in .NET 4. 编译器即服务功能已经在Mono中提供了很长一段时间,并且有迹象表明它可能出现在.NET 5或6中,但它在.NET 4中不可用。

If you absolutely, positively, need to run on .NET (note that Mono runs on Windows just fine, so you don't actually lose anything by running Mono), one interesting option might be to investigate how hard it would be to port Mono.CSharp to .NET. 如果你绝对肯定需要在.NET上运行(注意Mono在Windows上运行得很好,所以你实际上没有通过运行Mono失去任何东西),一个有趣的选择可能是调查移植Mono.CSharp有多难Mono.CSharp到.NET。 I mean, ultimately, at some point, it generates CIL bytecode which works exactly the same across all CLI implementations whether that be Mono, .NET, DotGNU, Rotor, Bartok or whatever. 我的意思是,最终,在某些时候,它生成的CIL字节码在所有CLI实现中都是完全相同的,无论是Mono,.NET,Do​​tGNU,Rotor,Bartok还是其他什么。

Otherwise, your options are pretty much the same they have always been: generate files and call the commandline compier, use DLR trees, use lightweight code generation, use Reflection.Emit , use CodeDOM, use CSharpCodeProvider , create your own scripting language, host some other scripting language or host the DLR. 否则,您的选项与以往几乎相同:生成文件并调用命令行编译器,使用DLR树,使用轻量级代码生成,使用Reflection.Emit ,使用CodeDOM,使用CSharpCodeProvider ,创建自己的脚本语言,托管一些其他脚本语言或托管DLR。

I'd probably go for the latter: hosting the DLR is absolutely easy and it gives you access to not only one but several good scripting languages (at the moment Ruby, Python, ECMAScript and Scheme) and in fact the user can use any DLR language they have installed on their machine. 我可能会选择后者:托管DLR非常简单,它不仅可以访问一种而且可以访问几种优秀的脚本语言(目前是Ruby,Python,ECMAScript和Scheme),实际上用户可以使用任何 DLR他们在自己的机器上安装的语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM