通过Roslyn构建自己的C#脚本(更新版)(转)
http://www.cnblogs.com/TianFang/p/6939723.html
之前写过文章介绍过如何通过Roslyn构建自己的C#脚本,但那篇文章是参考自Roslyn CTP版的,记得本来想等到Roslyn正式版出来重新更新一下文档的,不过记得后来Roslyn是跳票了的,Scripting API在正式版本中都一度被移除了,这个更新就没有做下去了。
年了,使用方法与之前已经大有不同了,便重新写一篇介绍下如何使用C# Script。
C# Interactive窗口
微软在Visual Studio中已经提供了一个C#交互窗口,通过它就可以直接执行C# 脚本语句。

这个窗口是非常强大的,支持语法高亮,智能提示,使用起来是非常方便的。简单的一些静态函数测试可以直接在该窗口中进行,还是非常方便的。
C#命令行接口
C#交互窗口方式虽然很方便,但我们很多时候是希望脚本程序能脱离VisualStudio单独执行,此时我们可以用到的命令行程序csi.exe。

一方面csi程序可以以REPL方式执行输入的命令,另一方面它可以可以执行执行脚本文件。
一个简单的示例程序如下(注:可以在VS中编写CSX文件,VS2017就已经有语法高亮和智能提示支持了)
//hello .csx
using System;
var msg = "Hello";
Console.WriteLine(msg);
执行指令如下: csi hello.csx
这样,我们就可以像脚本语言那样加载我们的C#程序了
另外,关于C# Script语法,基本上和C#差不多,主要多了如下两个:
- #load 用来加载别的脚本文件
- #r 用来加载dll
例如
#load "setup.csx"
#r "nunit.core.dll"
#r "nunit.core.interfaces.dll"
我还没有找到官方的文档(谁知道的话请告知),有一些第三方文档可以参考下:Writing a script
C# Scripting API
更进一步的,我们可以把脚本程序动态集成到我们的应用程序中,此时就要用到C# Scripting API了。要使用C# Script API,首先需要.net framework 4.6或.net core 1.0以上环境。
然后安装Nuget程序包:Install-Package Microsoft.CodeAnalysis.CSharp.Scripting
首先来个简单的计算:
object result = await CSharpScript.EvaluateAsync("1 + 2");
int result = await CSharpScript.EvaluateAsync<int>("1 + 2");
异常处理也是可以的:

try
{
Console.WriteLine(await CSharpScript.EvaluateAsync("2+2"));
}
catch (CompilationErrorException e)
{
Console.WriteLine(string.Join(Environment.NewLine, e.Diagnostics));
}

带上下文状态执行:
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);
添加程序集引用:
var result = await CSharpScript.EvaluateAsync("System.Net.Dns.GetHostName()",
ScriptOptions.Default.WithReferences(typeof(System.Net.Dns).Assembly));
添加using导入
var result = await CSharpScript.EvaluateAsync("Sqrt(2)",
ScriptOptions.Default.WithImports("System.Math"));
和宿主程序中的对象交互:

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

作为脚本重复执行:
var script = CSharpScript.Create<int>("X*Y", globalsType: typeof(Globals));
script.Compile();
for (int i = 0; i < 10; i++)
{
Console.WriteLine((await script.RunAsync(new Globals { X = i, Y = i })).ReturnValue);
}
脚本也可以携带上下文状态:
var script = CSharpScript.Create<int>("int x = 1;").
ContinueWith("int y = 2;").
ContinueWith("x + y");
Console.WriteLine((await script.RunAsync()).ReturnValue);
当然除了Roslyn外,也有一些第三方的脚本解决方案,使用时也可以参考一下。
- Nake (.Net Framework & Mono)
- dotnet script (.NET Core)
参考文章:
通过Roslyn构建自己的C#脚本(更新版)(转)的更多相关文章
- 通过Roslyn构建自己的C#脚本(更新版)
之前写过文章介绍过如何通过Roslyn构建自己的C#脚本,但那篇文章是参考自Roslyn CTP版的,记得本来想等到Roslyn正式版出来重新更新一下文档的,不过记得后来Roslyn是跳票了的,Scr ...
- 通过Roslyn构建自己的C#脚本
通过Roslyn构建自己的C#脚本 在下一代的C#中,一个重要的特性就是"Compiler as a Service",简单的讲,就是就是将编译器开放为一种可在代码中调用的服务.最 ...
- 10个工具让你的 shell 脚本更强大
10个工具让你的 shell 脚本更强大 很多人误以为shell脚本只能在命令行下使用.其实shell也可以调用一些GUI组件,例如菜单,警告框,进度条等等.你可以控制最终的输出,光标位 置还有各种输 ...
- Jenkins构建完成之后运行脚本可以杀掉TomCat但是起不来的解决方法
Jenkins构建完成之后运行脚本可以杀掉TomCat但是起不来的解决方法 写了一个重启tomcat的脚本,让jenkins编译.打包.发布时调用.在本地写好重启tomcat的脚本后,本地执行脚本没有 ...
- 最简单的基于FFmpeg的视频编码器-更新版(YUV编码为HEVC(H.265))
===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...
- Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载(2011年5月12日更新版)
MSDN于2011年5月12日,最新发布简体中文Windows 7 Ultimate 旗舰版 SP1 DVD镜像安装包,分32位和64位两个版本.最新发行代号分别是:677486(32位),67740 ...
- 微软开放技术发布针对 Mac 和 Linux 的更新版 Azure Node.JS SDK 和命令行工具
发布于 2013-12-04 作者 Eduard Koller 这次为我们使用Linux 的朋友带来了更多关于部署云上虚拟机的消息.今天,微软开放技术有限公司 (MS Open Tech),想与大家分 ...
- (转载)Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载(2011年5月12日更新版)
MSDN于2011年5月12日,最新发布简体中文Windows 7 Ultimate 旗舰版 SP1 DVD镜像安装包,分32位和64位两个版本.最新发行代号分别是:677486(32位),67740 ...
- 探索Antlr(Antlr 3.0更新版)
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://www.blogbus.com/dreamhead-logs/10756716.html <探索Antlr> ...
随机推荐
- mySQL 教程 第8章 视图
创建视图的目的 简单 隐藏数据复杂性 安全 可以对视图授权 数据独立 可以屏蔽表结构变化对用户的影响,比如增加列,更改列名 创建视图 1. 创建单表视图 以下视图显示JAVA班的学生姓名.身份证号和班 ...
- Splunk 交流
1. 初识splunk Splunk Enterprise Splunk Free Splunk Universal Forwarder,通用转发器
- [UE4]换枪需要做的事,容器:数组、集合、Map
换枪: 1.需要同时保存多把枪 2.换下去的枪需要隐藏,而不是销毁 3.换枪应该有动作 4.不同的枪应该有不同的行为 蓝图中常见的容器 1.数组 特点: 1.元素连续存放 2.通过索引访问 3.索引从 ...
- [UE4]GetWorld()->GetDeltaSeconds()方法
void AAvatar::Yaw(float amount) { if (Controller && amount) { // AddControllerYawInput()函数用于 ...
- 推荐一个lamp的一键安装包
本来我是一直用的nginx的,现在安全者的服务器是用的tengine,稳定性就不用多说了! 前段时间用thinkphp写了两个两个项目,刚开始放到了国外的服务器上,环境也是lnmp的,最后发现ngin ...
- 【转载】Docker 经验之谈
本文来源:Ghostcloud原创 对于用户来说,可能一开始在不了解的情况下会对容器报以拒绝的态度,但是在尝到容器的甜头.体验到它的强大性能之后,相信大家最终是无法抵挡其魅力的.容器技术能够解 ...
- 第1课 学习 C++ 的意义
1. 回顾历史 (1)UNIX操作系统诞生之初是直接用汇编语言写成的.随着UNIX的发展,汇编语言的开发效率成为一个瓶劲. (2)1971年,Ken Thompson和Denis Ritchie对B ...
- 批处理框架-spring Batch
并发处理业务 数据量大,并发度高,要支持事物,回滚,并发机制.事务.并发.监控.执行等,并不提供相应的调度功能.因此,如果我们希望批处理任务定期执行,可结合 Quartz 等成熟的调度框架实现. 业务 ...
- mysql数据表自动导为python sqlalchemy可操作对象
1.pip install sqlacodegen pip install pymysql 在/usr/lib/python/site-packages/sqlacodegen/main.py中添 ...
- Java面向对象之抽象类
内容: 1.抽象类的产生 2.抽象类和抽象方法的定义与使用 3.抽象类和抽象方法的注意事项 4.实例分析 1.抽象类的产生 当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的功能具 ...