之前写过文章介绍过如何通过Roslyn构建自己的C#脚本,但那篇文章是参考自Roslyn CTP版的,记得本来想等到Roslyn正式版出来重新更新一下文档的,不过记得后来Roslyn是跳票了的,Scripting API在正式版本中都一度被移除了,这个更新就没有做下去了。

最近看到有人在原文中询问如何使用C# Script API,便查询了一下相关资料,这个功能是在的VS2015 update 1中才正式放出的,其时已经到16年了,使用方法与之前已经大有不同了,便重新写一篇介绍下如何使用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;
}

, Y =  };
Console.WriteLine(await CSharpScript.EvaluateAsync<int>("X+Y", globals: globals));

作为脚本重复执行:

var script = CSharpScript.Create<int>("X*Y", globalsType: typeof(Globals));
script.Compile();
; i < ; 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外,也有一些第三方的脚本解决方案,使用时也可以参考一下。

参考文章:

通过Roslyn构建自己的C#脚本(更新版)的更多相关文章

  1. 通过Roslyn构建自己的C#脚本(更新版)(转)

      http://www.cnblogs.com/TianFang/p/6939723.html   之前写过文章介绍过如何通过Roslyn构建自己的C#脚本,但那篇文章是参考自Roslyn CTP版 ...

  2. 通过Roslyn构建自己的C#脚本

    通过Roslyn构建自己的C#脚本 在下一代的C#中,一个重要的特性就是"Compiler as a Service",简单的讲,就是就是将编译器开放为一种可在代码中调用的服务.最 ...

  3. 10个工具让你的 shell 脚本更强大

    10个工具让你的 shell 脚本更强大 很多人误以为shell脚本只能在命令行下使用.其实shell也可以调用一些GUI组件,例如菜单,警告框,进度条等等.你可以控制最终的输出,光标位 置还有各种输 ...

  4. Jenkins构建完成之后运行脚本可以杀掉TomCat但是起不来的解决方法

    Jenkins构建完成之后运行脚本可以杀掉TomCat但是起不来的解决方法 写了一个重启tomcat的脚本,让jenkins编译.打包.发布时调用.在本地写好重启tomcat的脚本后,本地执行脚本没有 ...

  5. 最简单的基于FFmpeg的视频编码器-更新版(YUV编码为HEVC(H.265))

    ===================================================== 最简单的基于FFmpeg的视频编码器文章列表: 最简单的基于FFMPEG的视频编码器(YUV ...

  6. Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载(2011年5月12日更新版)

    MSDN于2011年5月12日,最新发布简体中文Windows 7 Ultimate 旗舰版 SP1 DVD镜像安装包,分32位和64位两个版本.最新发行代号分别是:677486(32位),67740 ...

  7. 微软开放技术发布针对 Mac 和 Linux 的更新版 Azure Node.JS SDK 和命令行工具

    发布于 2013-12-04 作者 Eduard Koller 这次为我们使用Linux 的朋友带来了更多关于部署云上虚拟机的消息.今天,微软开放技术有限公司 (MS Open Tech),想与大家分 ...

  8. (转载)Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载(2011年5月12日更新版)

    MSDN于2011年5月12日,最新发布简体中文Windows 7 Ultimate 旗舰版 SP1 DVD镜像安装包,分32位和64位两个版本.最新发行代号分别是:677486(32位),67740 ...

  9. 探索Antlr(Antlr 3.0更新版)

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://www.blogbus.com/dreamhead-logs/10756716.html <探索Antlr> ...

随机推荐

  1. luoguP2735 电网 Electric Fences

    一道校内模拟赛遇见的题 ** 不会正解就真的很麻烦的 数学题 ** 有一种东西叫 皮克定理 发现的千古神犇: 姓名:George Alexander Pick(所以叫皮克定理呀 国籍:奥地利(蛤!竟然 ...

  2. VFS,super_block,inode,dentry—结构体图解

    总结: VFS只存在于内存中,它在系统启动时被创建,系统关闭时注销. VFS的作用就是屏蔽各类文件系统的差异,给用户.应用程序.甚至Linux其他管理模块提供统一的接口集合. 管理VFS数据结构的组成 ...

  3. 如何使用 JMeter 调用你的 Restful Web Service?进行简单的压力测试和自动化测试

    表述性状态传输(REST)作为对基于 SOAP 和 Web 服务描述语言(WSDL)的 Web 服务的简单替代,在 Web 开发上得到了广泛的接受.能够充分证明这点的是主流 Web 2.0 服务提供商 ...

  4. pip常用命令总结(转载)

    基本的命令解释,如下图: 列出已安装的包 pip freeze or pip list 导出requirements.txt pip freeze > <目录>/requiremen ...

  5. spark java API 实现二次排序

    package com.spark.sort; import java.io.Serializable; import scala.math.Ordered; public class SecondS ...

  6. LOADRUNNER连接ORACLE数据库的方法

    LOADRUNNER连接ORACLE数据库的方法     最近正在做一个测试数据库性能的项目,直接写出来的连接数据库并且进行数据库查询和插入的脚本在VUSER_INIT中(连接数据库)#include ...

  7. 006 ajax验证用户名

    1.大纲 2.index.jsp <%@ page language="java" contentType="text/html; charset=UTF-8&qu ...

  8. 三、django rest_framework源码之权限流程剖析

    1 绪言 上一篇中分析了认证部分的源码,认证后的下一个环节就是权限判定了.事实上,权限判定肯定要与认证联合使用才行,因为认证部分不会对请求进行禁止或者是允许,而只是根据请求中用户信息进行用户身份判断, ...

  9. Redis和MySQL数据一致中出现的几种情况

    1. MySQL持久化数据,Redis只读数据 redis在启动之后,从数据库加载数据. 读请求: 不要求强一致性的读请求,走redis,要求强一致性的直接从mysql读取 写请求: 数据首先都写到数 ...

  10. HTTP 缓存之ETag 和Cache-Control的使用方法介绍

    什么是http缓存,有什么作用 通过网络获取内容既速度缓慢又开销巨大.较大的响应需要在客户端与服务器之间进行多次往返通信,这会延迟浏览器获得和处理内容的时间,还会增加访问者的流量费用.因此,缓存并重复 ...