Roslyn可以用来生成类似于DynamicMethod IL生成的动态方法 [英] Can Roslyn be used to generate dynamic method similar to DynamicMethod IL generation

查看:1496
本文介绍了Roslyn可以用来生成类似于DynamicMethod IL生成的动态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用DynamiMethod生成IL使用

I have been using DynamiMethod to generate the IL using

method.GetILGenerator();

这很好,但是当然很难使用,因为你一般不想使用低级IL在高级语言如C#。现在,因为有Roslyn我,虽然我可以使用它。我试图找出如何使用Roslyn做类似的事情:生成一个动态方法,然后为它创建一个委托。我可以这样做的唯一方法是拥有像这样的完整类

This works well but is of course very hard to use since you generally don't want to work with low level IL in a high level language like C#. Now since there is Roslyn I though I can use that instead. I have tried to figure out how to use Roslyn to do similar thing: generate a dynamic method and then create a delegate for it. The only way I was able to do that is to have full class like this

SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(@"
using System;

namespace RoslynCompileSample
{
    public class Writer
    {
        public void Write(string message)
        {
            Console.WriteLine(message);
        }
    }
}");

然后代替Write方法,我可以使用字符串连接插入我的方法。之后,在内存中生成动态装配,并使用反射来获取所需的方法并生成委托。

Then instead of the Write method I can insert my method inside using string concatenation. After that dynamic assembly is generated in memory and loaded and reflection is used to get the required method and generate the delegate.

这种方法似乎很好,但似乎有点一个overkill为我的情况,我将需要使用多个独立的方法,可能导致大量的程序集加载。

This method seems to work fine but seems a bit of an overkill for my case as I will need to use multiple independent methods possible leading to lots of assemblies being loaded.

所以问题是:有一个简单的方法来做类似于Roslyn的动态方法,所以我只能定义一个方法的主体连接到一个类型?如果不是,编译许多动态程序集时有很大的缺点(例如太多无法加载等)。

So the question is: Is there an easy way to do something similar to dynamic method for Roslyn, so that I can only define a body of the method attached to a type? If not, is there any big drawback in compiling many dynamic assemblies (like too many can't be loaded, etc...)

推荐答案

您可以使用 CSharpScript 类。 await CSharpScript.EvaluateAsync(1 + 2)只是计算表达式。您可以在 Microsoft.CodeAnalysis.Scripting.CSharp 包中找到它(目前只有预发布版本)。

You can use CSharpScript class. await CSharpScript.EvaluateAsync("1 + 2") just evaluates the expression. You can find it in Microsoft.CodeAnalysis.Scripting.CSharp package (currently only prerelease version). Add usings and assembly references using ScriptOptions (second parameter).

编译要委托的表达式:

var func = CSharpScript.Create<int>("1 + 3").CompileToDelegate()

使用全局对象将某些内容传递给函数:

Passing something to the function using globals object:

await CSharpScript.Create<int>("1 + x", 
     ScriptOptions.Default.AddReferences(typeof(Program).Assembly),
     globalsType:  typeof(ScriptGlobals))
    .CreateDelegate()
    .Invoke(new ScriptGlobals() { x = 4 });

这篇关于Roslyn可以用来生成类似于DynamicMethod IL生成的动态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆