如何在运行CSharpScript前为变量赋值或传入对象实例?
在运行前向CSharpScript传递变量/对象实例的方法
当然可以在运行脚本前为变量赋值或传入对象实例,不需要先运行脚本获取ScriptState再操作。以下是几种实用的实现方式:
1. 通过ScriptOptions添加全局变量
这种方式可以在编译脚本前直接注入简单变量或对象实例,脚本中可直接使用这些全局变量:
using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting; // 提前准备要传入的变量值 int num = 4; string hostMessage = "来自宿主的消息"; // 构建ScriptOptions,注入全局变量 var scriptOptions = ScriptOptions.Default .AddGlobalVariable("a", num) .AddGlobalVariable("hostGreeting", hostMessage); // 创建并运行脚本,可直接使用注入的变量 var script = CSharpScript.Create(@" Console.WriteLine(""变量a的值:"" + a); Console.WriteLine(hostGreeting); ", scriptOptions); await script.RunAsync();
2. 传入自定义宿主对象(适合复杂实例)
如果需要传递包含属性、方法的复杂对象,推荐使用宿主对象的方式,脚本可以直接访问对象的成员:
// 定义宿主类 public class ScriptHost { public int Counter { get; set; } public void Log(string content) => Console.WriteLine($"宿主日志:{content}"); } // 初始化宿主实例并赋值 var hostInstance = new ScriptHost { Counter = 100 }; // 注入宿主对象到脚本上下文 var options = ScriptOptions.Default .AddGlobalVariable("host", hostInstance); // 脚本中直接操作宿主对象 var script = CSharpScript.Create(@" host.Counter += 10; host.Log(""Counter更新为:"" + host.Counter); ", options); await script.RunAsync(); // 运行后hostInstance.Counter的值会变为110
3. 使用参数化脚本入口
可以在脚本中定义带参数的方法,编译后调用时传入参数,这种方式更接近常规的函数调用逻辑:
// 创建包含参数化方法的脚本 var script = CSharpScript.Create(@" public static void Execute(int inputNum, string inputStr) { Console.WriteLine($"输入数字:{inputNum}"); Console.WriteLine($"输入字符串:{inputStr}"); } "); // 编译脚本 var compiledScript = await script.CompileAsync(); // 运行脚本后调用方法并传入参数 var scriptState = await compiledScript.RunAsync(); var executeMethod = scriptState.Globals.GetMember("Execute").Value as Action<int, string>; executeMethod?.Invoke(200, "参数化调用示例");
以上几种方法都不需要先运行脚本再通过ScriptState赋值,而是在编译阶段就完成了上下文注入,或者在调用时直接传递参数,完全满足你在运行前传递数据的需求。
内容的提问来源于stack exchange,提问作者BiddahProphet
相关产品推荐
相关产品推荐

