当前位置: 首页 > news >正文

C# CSharpScript 的原理与应用

CSharpScript 是 Roslyn 编译器提供的脚本 API,允许在运行时动态执行 C# 代码。以下是其核心原理和典型应用场景:

一、核心原理

1. 架构基础

  • 基于 Roslyn 编译器即服务(Compiler as a Service)

  • 将代码文本实时编译为内存中的程序集

  • 通过反射或轻量级代码生成执行

2. 执行流程

源代码 → 语法分析 → 绑定 → 编译 → 内存程序集 → 执行

3. 关键技术

  • 增量编译:重复执行时复用部分编译结果

  • 脚本会话:通过 ScriptState 保持执行上下文

  • 对象传递:通过 globals 参数实现宿主与脚本的数据交换

二、基础应用

1. 基本执行

var result = await CSharpScript.EvaluateAsync("1 + 2");
Console.WriteLine(result); // 输出 3

2. 带上下文执行

public class Globals { public int X = 1, Y = 2; }
var globals = new Globals();var result = await CSharpScript.EvaluateAsync<int>("X + Y", globals: globals);

3. 多步执行

var state = await CSharpScript.RunAsync("int x = 1;");
state = await state.ContinueWithAsync("int y = 2;");
state = await state.ContinueWithAsync("x + y");
Console.WriteLine(state.ReturnValue); // 输出 3

三、高级特性

1. 自定义引用和导入

var options = ScriptOptions.Default.WithReferences(typeof(DateTime).Assembly).WithImports("System.Math");var result = await CSharpScript.EvaluateAsync<double>("Sqrt(4)", options);

2. 异常处理

try
{await CSharpScript.EvaluateAsync("throw new Exception(\"Test\");");
}
catch (CompilationErrorException e)
{Console.WriteLine(string.Join("\n", e.Diagnostics));
}

3. 性能优化

// 预编译脚本
var script = CSharpScript.Create<int>("X * Y", globalsType: typeof(Globals));
var compiled = script.Compile();// 重复执行时使用编译结果
for (int i = 0; i < 100; i++)
{var result = await script.RunAsync(new Globals { X = i, Y = i });
}

四、典型应用场景

1. 动态规则引擎

var rule = "input.Age > 18 && input.Score > 60";
var result = await CSharpScript.EvaluateAsync<bool>(rule, globals: new { input = new { Age = 20, Score = 70 } });

2. 公式计算器

var formula = "Math.Sin(x) + Math.Cos(y)";
var options = ScriptOptions.Default.WithImports("System.Math");
var calculate = ScriptOptions.Default.WithReferences(typeof(Math).Assembly);var result = await CSharpScript.EvaluateAsync<double>(formula, globals: new { x = 1.0, y = 2.0 }, options);

3. 插件系统

string pluginCode = """using PluginBase;public class MyPlugin : IPlugin {public string Execute() => "Hello from plugin";}return new MyPlugin();""";var options = ScriptOptions.Default.WithReferences(typeof(IPlugin).Assembly).WithImports("PluginBase");var plugin = await CSharpScript.EvaluateAsync<IPlugin>(pluginCode, options);
Console.WriteLine(plugin.Execute());

五、性能注意事项

  1. 编译开销:首次执行较慢(约100-500ms)

  2. 内存占用:每个脚本会生成内存程序集

  3. 最佳实践

    • 预编译高频使用的脚本

    • 复用 ScriptOptions 实例

    • 避免在循环中动态编译

六、安全限制

  1. 代码访问控制

var options = ScriptOptions.Default.WithReferences(/* 白名单程序集 */);
  1. 沙箱方案

AppDomain sandbox = AppDomain.CreateDomain("Sandbox");
try {// 在沙箱中执行脚本
}
finally {AppDomain.Unload(sandbox);
}

七、Helloworld

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;public class TestController
{public List<string> Output { get; set; } = new List<string>(); // 改为可读写
}class Program
{static async Task<int> Main(string[] args){var controller = new TestController();var remainingCodeTxt = """Output.Add("Hello,world!");return Output; """;try{// 执行脚本var result = await CSharpScript.EvaluateAsync<List<string>>(remainingCodeTxt,globals: controller,options: ScriptOptions.Default.WithImports("System.Collections.Generic").WithReferences(typeof(List<string>).Assembly));Console.WriteLine("Controller.Output: " + string.Join(", ", controller.Output));Console.WriteLine("脚本返回值: " + string.Join(", ", result));return 0;}catch (Exception ex){Console.WriteLine($"Error: {ex.Message}");return 1;}}
}

CSharpScript 为 C# 提供了强大的运行时代码执行能力,适用于需要动态性的场景,但需注意性能和安全性问题。

相关文章:

  • python校园拼团系统
  • Uniapp 中根据不同离开页面方式处理 `onHide` 的方法
  • uniapp的video遮盖了popup
  • Web安全性测试--超详细用例CASE整理总结
  • linux unix socket 通信demo
  • 理解RocketMQ顺序消息的全局有序消息和分区有序消息、延迟消息、事务消息
  • 英一真题阅读单词笔记 13年
  • JS数据类型检测方法总结
  • 大数据学习(140)-数仓概述分析
  • 你的下一把量化“瑞士军刀”?KHQuant适用场景全解析【AI量化第32篇】
  • FastAdmin退出登录不提示的修改方法
  • C#上位机通过WebApi对接DeepSeek
  • 关于球面投影SphericalProjector的介绍以及代码开发
  • C语言——共用体
  • CppCon 2017 学习:C++ atomics:from basic to advanced. What do they do?
  • 银河麒麟 | ubuntu 安装运用 docker 容器,实现容器化部署项目
  • Ubuntu服务器启动jupyter notebook,本地电脑Mobaxterm访问
  • Git 版本控制系统
  • Web攻防-XSS跨站浏览器UXSS突变MXSSVueReactElectron框架JQuery库写法和版本
  • OpenStack体验
  • wordpress 摘要/衡阳seo外包
  • 兴义市住房城乡建设局网站/免费好用的网站
  • 创建网站数据库/企业危机公关
  • 营销咨询报告/惠州seo推广外包
  • 张店网站建设公司/宁波网站建设推广公司价格
  • 免费自己做网站/个人推广平台