溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用Roslyn編譯器服務(wù)

發(fā)布時(shí)間:2021-11-10 17:23:13 來(lái)源:億速云 閱讀:179 作者:柒染 欄目:大數(shù)據(jù)

本篇文章給大家分享的是有關(guān)如何使用Roslyn編譯器服務(wù),小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

.NET Core和 .NET 4.6中 的C# 6/7 中的編譯器Roslyn 一個(gè)重要的特性就是"Compiler as a Service",簡(jiǎn)單的講,就是就是將編譯器開(kāi)放為一種可在代碼中調(diào)用的服務(wù), 通常在工作流引擎 或是規(guī)則引擎中都需要一項(xiàng)功能是計(jì)算表達(dá)式, 在沒(méi)有Roslyn 之前我通常借助于Antlr [Antlr(“又一個(gè)語(yǔ)言識(shí)別工具”的縮寫(xiě))是一個(gè)最初用Java編寫(xiě)的庫(kù),可以根據(jù)特殊的語(yǔ)法(文法)來(lái)構(gòu)建復(fù)雜的解析器代碼。它就像是一個(gè)用于語(yǔ)言解析的加強(qiáng)版的正則表達(dá)式。你可以編寫(xiě)某種語(yǔ)言的語(yǔ)法規(guī)則,Antlr會(huì)為你生成代碼],基于Antlr 有一個(gè)輕量級(jí)的C#編譯器服務(wù)Expression Evaluator 。

要在自己的代碼中使用Roslyn 執(zhí)行C#腳本,首先進(jìn)行如下幾步準(zhǔn)備工作。

1、通過(guò)Nuget 安裝Microsoft.CodeAnalysis.CSharp.Scripting

2、在代碼中增加如下命名空間的引用。

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;

經(jīng)典的HelloWorld

首先還是以經(jīng)典的Hello World來(lái)開(kāi)始介紹如何執(zhí)行腳本吧。

static void Main(string[] args)
    {
           var options =
               ScriptOptions.Default
              .AddReferences("System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");

           var bar = new Bar() { StaffId = 5686, UnitId = 2 , Age = 15};
           Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync("System.Console.WriteLine(\"hello world\");", options);

    }

從上述代碼中可以看出,執(zhí)行一個(gè)腳本還是比較簡(jiǎn)單的, 可以通過(guò)Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync() 函數(shù)執(zhí)行自己的腳本了,如果我們要獲取腳本的返回值,也是很容易的。

var scriptState = CSharpScript.RunAsync<int>("3+2*5", ScriptOptions.Default);

Console.WriteLine(scriptState );

在會(huì)話中執(zhí)行腳本

很多時(shí)候,我們無(wú)法一次執(zhí)行所有的腳本,而是像shell中那樣輸入一句執(zhí)行一句的。假如我們執(zhí)行如下代碼

Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync("var i = 3;");
var result = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync("i * 2");

得到的并不是我們想要的結(jié)果6,而是一個(gè)異常:

如何使用Roslyn編譯器服務(wù)

究其原因,是因?yàn)镃SharpScript.RunAsync 函數(shù)每次都是在一個(gè)單獨(dú)的上下文中執(zhí)行的,并不會(huì)和前面的語(yǔ)句產(chǎn)生關(guān)聯(lián)。如果我們要在CSharpScript.Create()函數(shù)創(chuàng)建一個(gè)腳本,通過(guò)函數(shù)ContinueWith 組成一個(gè)完整的腳本運(yùn)行。正確方式如下:

var s0 = CSharpScript.Create("int x = 1;");
           var s1 = s0.ContinueWith("int y = 2;");           
           var s2 = s1.ContinueWith<int>("x + y");
           Console.WriteLine(s2.RunAsync().Result.ReturnValue);

在腳本和程序中共享數(shù)據(jù)

我們?cè)趫?zhí)行腳本時(shí),除了獲取腳本的輸出外,許多時(shí)候需要設(shè)置腳本的輸入,要設(shè)置輸入的方式也有許多。最直接的方式拼接腳本但這么做的效率和可維護(hù)性是十分差的。另外也可以通過(guò)傳統(tǒng)的IPC通信機(jī)制——文件、Socket等方式,這種方式一來(lái)比較麻煩,二來(lái)對(duì)于復(fù)雜的對(duì)象來(lái)說(shuō),還牽涉到序列化,也是非常不便。

Roslyn提供了一個(gè)更為簡(jiǎn)單有效的解決辦法:在會(huì)話中傳入一個(gè)宿主對(duì)象,會(huì)話中的腳本程序也能訪問(wèn)宿主對(duì)象的各成員變量。

namespace RoslynCosonle
{
    class Program
    {
        static void Main(string[] args)
        {
            var options =
                ScriptOptions.Default
               .AddReferences("System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");         

            var s0 = CSharpScript.Create("int x = 1;");
            var s1 = s0.ContinueWith("int y = 2;");           
            var s2 = s1.ContinueWith<int>("x + y");
            Console.WriteLine(s2.RunAsync().Result.ReturnValue);

           var bar = new Bar() { StaffId = 5686, UnitId = 2 , Age = 15};
            Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync("System.Console.WriteLine( (StaffId==5686 && UnitId==2)||( UnitId == 3|| Age >10) );", options, bar);

 
        }
    }

    public class Bar
    {
        public string Foo => "Hello World!";
       
        public int StaffId { get; set; }

        public int UnitId { get; set; }

        public int Age { get; set; }
    }

通過(guò)對(duì)象Bar 把握的輸入傳給表達(dá)式,然后表達(dá)式就可以計(jì)算結(jié)果,這個(gè)就是我們?cè)诠ぷ髁饕胬锩嬉谋磉_(dá)式計(jì)算了。

以上就是如何使用Roslyn編譯器服務(wù),小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI