Skripterstellung in C # oder dynamische Ausführung zur Laufzeit

Hallo Habr!





Ich denke, nur wenige Leute wissen, dass C # so etwas wie eine Bewertung aus anderen Sprachen hat. Dank der Roslyn-API können Sie Ihren C # -Code zur Laufzeit kompilieren und ausführen. Sie können ein Verwendungsbeispiel in meiner REPL- Implementierung für C # sehen.





Ich habe so etwas wie REPL kennengelernt, als ich Python berührt habe. In der .NET-Welt gibt es eine ähnliche Sache namens C # Interactive (CSI). Ziemlich praktisch, hat aber einen großen Nachteil: Es ist in den Visual Studio-Tools enthalten. Ohne die Installation von VS können Sie es also nicht verwenden. Um es auszuführen, ohne VS zu starten, müssen Sie darauf zugreifen Die Tiefen (oder besser gesagt die Ausführung über die Konsole C: \ Programme (x86) \ Microsoft Visual Studio \ 2019 \ Community \ Common7 \ Tools \ VsDevCmd.bat) sind möglicherweise nicht bequem genug.





Darüber hinaus gibt es Projekte wie Dotnet-Skript und cs-Skript (sie arbeiten durch Microsoft.CodeAnalysis.CSharp.Scripting ), aber sie haben einen fatalen Fehler - sie nicht von mir geschrieben wurden. So kam die Idee, ein eigenes ungeschicktes Fahrrad zu schreiben, aber mit eigenen Funktionen (die auch ungeschickt funktionieren)!. Nach einer kurzen Suche fiel mein Blick auf dieses Wunder: Microsoft.CodeAnalysis.CSharp.Scripting . Einer der Vorteile ist eine praktische API, die die Ausführung von Code ohne Klassen und Namespaces ermöglicht.





Zuerst müssen Sie das Microsoft.CodeAnalysis.CSharp.Scripting- Paket installieren und verwenden





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



CSharpScript ist eine statische Klasse, die uns beim Erstellen eines Skripts hilft. Sie enthält drei Methoden:





  • Create - Script ,





  • RunAsync - , ScriptState





  • EvaluateAsync -





CSharpScript.Create , .





var script = CSharpScript.Create("System.Console.WriteLine(\"Hello from script\")");
script.Compile();
await script.RunAsync();
      
      



E Compile(), .





ScriptOptions, namespace- reference- ( , using static).





  var options = ScriptOptions.Default
            .AddImports("System", "System.IO", "System.Collections.Generic",
                "System.Console", "System.Diagnostics", "System.Dynamic",
                "System.Linq", "System.Text",
                "System.Threading.Tasks")
            .AddReferences("System", "System.Core", "Microsoft.CSharp");

 CSharpScript.Create("Console.WriteLine(\"Hello from script\")", options);
      
      



— ScriptOptions - namespace-. whitelist, , , .





CSharpScript.RunAsync ScriptState, ContinueWithAsync, , ScriptState. , Script. , ReturnValue.





ScriptState state = await CSharpScript.RunAsync("int x = 5;");
state = await state.ContinueWithAsync<int>("x + 1");
Console.WriteLine(state.ReturnValue); // 6
      
      



state , exception





foreach(var variable in state.Variables)
{
	Console.WriteLine($"{variable.Name} - {variable.Value}");
}
      
      



CSharpScript.Create ,





var script = CSharpScript.Create<Func<int,int>>("x => x+1");
Console.WriteLine(await script.CreateDelegate().Invoke(1)); // 2
      
      



, - , CSharpScript.EvaluateAsync ( , )





var deleg = await CSharpScript.EvaluateAsync<Func<int, int>>("x => x * 2");
Console.WriteLine(deleg(5)); // 10
      
      



- ( , , ).





CSharpScript globals globalsType (globalsType , globals), , ( CSharpScript.Create globalsType, script.RunAsync() globals).





var res = await CSharpScript.EvaluateAsync<int>("X+Y", globals: new GlobalValues());
Console.WriteLine(res); // 100

public class GlobalValues 
{
	public int X = 25;
	public int Y = 75;
}
      
      



:





, , . .





Microsoft.CodeAnalysis.CSharp.Scripting, , runtime C# . , , .net .





5 github, :





:





https://github.com/dotnet/roslyn/blob/main/docs/wiki/Scripting-API-Samples.md





https://github.com/dotnet/roslyn/tree/a7319e2bc8cac34c34527031e6204d383d29d4ab/src/Scripting





Ich hoffe, mein erster Artikel schien nicht zu langweilig und ich konnte Ihnen irgendwie helfen.





Einen schönen Tag noch!








All Articles