C# Script

C# Script

In some cases, it is necessary to dynamically execute C# code during program runtime. For example, storing frequently changing algorithms in a configuration file and reading and executing them from the configuration file during runtime. C# scripts can be used to accomplish these tasks.

Last updated 12/24/2021 10:46 PM
寻找无名的特质
3 min read
Category
.NET
Tags
.NET C# Script

In some cases, C# code needs to be executed dynamically during program runtime. For example, certain frequently changing algorithms might be saved in a configuration file, then read and executed at runtime. In such scenarios, C# scripts can be used to accomplish this.

To use C# scripts, you need to reference the library Microsoft.CodeAnalysis.CSharp.Scripting. Below are some examples:

The most basic usage is to evaluate arithmetic expressions:

Console.Write("Test basic arithmetic expression: (1+2)*3/4");
var res = await CSharpScript.EvaluateAsync("(1+2)*3/4");
Console.WriteLine(res);

If more complex functions are needed, you can use WithImports to introduce namespaces:

Console.WriteLine("Test Math function: Sqrt(2)");
res = await CSharpScript.EvaluateAsync("Sqrt(2)", ScriptOptions.Default.WithImports("System.Math"));
Console.WriteLine(res);

Not only calculation functions, but other functions like IO are also supported:

Console.WriteLine(@"Test input/output function: Directory.GetCurrentDirectory()");
res = await CSharpScript.EvaluateAsync("Directory.GetCurrentDirectory()",
     ScriptOptions.Default.WithImports("System.IO"));
Console.WriteLine(res);

String functions can be called directly:

Console.WriteLine(@"Test string function: ""Hello"".Length");
res = await CSharpScript.EvaluateAsync(@"""Hello"".Length");
Console.WriteLine(res);

If you need to pass variables, you can pass an instance of a class as a context. The following example uses the Student class:

Console.WriteLine(@"Test variables:");
var student = new Student { Height = 1.75M, Weight = 75 };
await CSharpScript.RunAsync("BMI=Weight/Height/Height", globals: student);
Console.WriteLine(student.BMI);

Class Student:

public class Student
{
    public Decimal Height { get; set; }

    public Decimal Weight { get; set; }

    public Decimal BMI { get; set; }

    public string Status { get; set; } = string.Empty;
}

Scripts that are reused can be compiled once and reused:

Console.WriteLine(@"Test script compilation reuse:");
var scriptBMI = CSharpScript.Create<Decimal>("Weight/Height/Height", globalsType: typeof(Student));
scriptBMI.Compile();

Console.WriteLine((await scriptBMI.RunAsync(new Student { Height = 1.72M, Weight = 65 })).ReturnValue);

Functions can also be defined within the script:

Console.WriteLine(@"Test defining functions in script:");
string script1 = "decimal Bmi(decimal w,decimal h) { return w/h/h; } return Bmi(Weight,Height);";

var result = await CSharpScript.EvaluateAsync<decimal>(script1, globals: student);
Console.WriteLine(result);

Variables can also be defined within the script:

Console.WriteLine(@"Test variables in script:");
var script =  CSharpScript.Create("int x=1;");
script =  script.ContinueWith("int y=1;");
script =  script.ContinueWith("return x+y;");
Console.WriteLine((await script.RunAsync()).ReturnValue);

The complete example can be downloaded from GitHub: https://github.com/zhenl/CSharpScriptDemo

This article is from the blog park, author: Searching for the nameless trait, original link: https://www.cnblogs.com/zhenl/p/15714453.html

Keep Exploring

Related Reading

More Articles