二、Visual Studio 2017, C# 6, IDE 和 Roslyn

在本章中,我们将介绍:

  • 使用 Visual Studio 2017
  • 使用 Visual Studio 代码
  • 在 macOS 上安装和使用 omnsharp
  • 在 Linux 上安装和使用 omnsharp
  • 使用 Roslyn
  • 使用新的 c# 6 特性

介绍

在本章中,我们将了解 Visual Studio 2017 最有趣的新特性。 我们将使用 Visual Studio Code 作为 c#和其他一些语言的跨平台编辑器。

我们将在 macOS 和 Linux 的其他 ide 上安装OmniSharp库,以获得智能感知和语言支持的好处,就像 VS 所做的那样。

我们还将发现名为 Roslyn 的新的开源跨平台编译器,并了解它的不同 api 将给我们带来什么。

最后,我们将发现一些有用的和相关的 c# 6 新特性。

使用 Visual Studio 2017

VS 2017 有许多新的或增强的特性。 让我们来看看其中的一些。

怎么做……

  1. 功能一 vs 项目模板:

我们想要使用所有不一定可靠的项目,所以这取决于我们来验证。 出现“新建项目”对话框:

  1. Visual Studio Gallery 添加扩展:

  1. 搜索(类、方法、接口和许多其他):

  1. 代码片段:

VS 生成一个try/catch代码块,如下所示:

VS 生成一个if代码块,如下所示:

VS 生成一个foreach代码块,如下所示:

我们可以通过按Tabforeach语句之间导航来替换foreach语句的所有元素,然后按Enter进行验证。

我们可以通过https://msdn.microsoft.com/en-us/library/z41h7fat.aspx查询 MSDN 上的默认代码片段列表。

“代码段管理器”对话框中包含所有可用的代码段,如下所示:

  1. 代码映射:

此特性创建一个表示方法调用的层次结构的图,包括在调试期间它们的类和 DLL 容器。 此功能仅在 VS 2017 企业版中可用。

代码映射允许我们做以下事情:

  1. 分析:

NuGet中有许多可用的分析仪,包括TsqlAzureCSharp。 它们中的每一个都提高了代码的质量,类似于FxCop(一种代码,为您提供纠正代码建议的分析工具)。

让我们来探索其中之一——代码破解器:

While building an application, if a rule is not respected, it will appear in the error list, and if documentation exists about this error, we will be able to consult the page by clicking on the error number.

  1. 在即时窗口中使用 LINQ 和 Lambdas:

  1. Perfprmance tips:

我们可以在工具提示中获取性能信息,例如:

    1. 在方法的开始处创建一个断点
    2. 在方法的末尾创建另一个断点
    3. 在调试时,我们将看到,在第二个断点处,第一个和第二个断点之间经过的时间(以毫秒为单位):

  1. 诊断工具:

我们还可以查看堆的内容:

  1. 代码的镜头:

代码镜头是 VS 2017 的一个新特性,它可以实时显示我们在引用、单元测试和代码更改中的代码。 这些信息出现在方法名的上方:

  1. 在 Visual Studio 2017 中,我们可以在编写代码时动态地修复编码错误:

快速行动…… 菜单提供了许多可能的操作,这取决于上下文。

使用 Visual Studio 代码

VS Code 是一个跨平台的命令行文件文件夹编辑器。 它可以安装在 Windows、Linux 或 macOS 上。 我们可以把 VS Code 看作是一个跨平台的轻量级的 VS 版本。

准备

首先,让我们从https://code.visualstudio.com/下载 VS Code:

怎么做……

  1. 让我们通过双击VSCode-linux-x64文件夹中的 Code 来启动 VS Code:

这将打开 VS Code:

我们可以按F1让命令面板出现,这让你可以访问 VS Code 的所有功能。

这样,您还可以通过输入扩展名来浏览和安装扩展名。

To install extensions, you can go to the VS Marketplace (https://marketplace.visualstudio.com/#VSCode).

现在,我们将在 VS Code 中打开我们用 Yeoman 脚手架生成器(配方 3)创建的项目,并确保我们已经安装了 dotnet CLI。

  1. 让我们输入F1来打开 VS Code 中的命令行工具,输入.NET来智能提示我们可以使用 dotnet CLI 来恢复包:

  1. 我们选择dotnet restore命令:

  1. 我们可以在 Terminal 中看到前面的dotnet restore命令的执行:

  1. 让我们通过输入以下命令来运行 web 应用:
dotnet run

By default, Kestrel will use port 5004, and VS Code with Kestrel will use port 5000.

  1. 我们看到dotnet run在终端上执行:

  1. 现在我们可以通过http://localhost:5000/访问应用:

它是如何工作的…

VS Code 支持多种语言和技术:c#、JS、TypeScript、AngularJS、Less、GIT、HTML、JSON 和 SASS。 我们可以将 VS Code 与 Node.js 关联起来,以获得所有任务运行器特性的好处,比如 gulp 或 grunt。

我们将能够通过node 包管理器(npm)使用所有 node .js 特性,这是一个类似 Maven 或 NuGet 的包管理器。 也可以使用其他包管理器来安装 Node.js,比如 Windows 上的 Chocolatey 或者 macOS 上的 Homebrew。 我们也可以从官网(https://nodejs.org/en/download/)下载。

VS Code 有几个特性,其中一些如下所示:

  • 智能感知
  • 调试
  • 使用GIT特性的版本控制
  • 片段
  • 警告
  • 代码的行为
  • 去定义
  • 重构

调试可用于 c#、JavaScript 和 TypeScript。

在 macOS 上安装和使用 omnsharp

本食谱解释了什么是 omnsharp,如何安装它,以及如何在 macOS 上使用它。

怎么做……

在前面提到的大多数文本编辑器中,都包含一个包管理器,并将用于安装 omnsharp 包:

  1. 用 Atom 在 macOS 上编辑代码:

  1. 让我们在 Atom 上安装 omnsharp 包:

  1. 接下来,让我们创建一个新项目:

  1. 现在 omnsharp 已经安装好了,我们可以使用。net 项目的脚手架:

  1. 在选择 Web Application 之后,将生成项目和相关文件。

  2. 我们可以看到生成了Startup.cs类:

在图片的底部,我们可以看到 Atom 上的 omnsharp 特性,左下角有一个绿色的小 omnsharp 图标,还有两个面板:错误和警告窗格和 omnsharp 输出窗格。 页面底部的绿色小图标是 omnsharp 图标:

  1. 让我们输入一些代码; 我们将看到智能感知的行动:

  1. 我们可以看到在输入时输出窗口显示的内容:

  1. 我们还可以实时看到错误和警告:

  1. 通过右键点击打开上下文菜单,我们可以看到 omnsharp 菜单的功能:

它是如何工作的…

omnsharp 是一组开源工具和扩展,用于在 macOS 和 Linux 代码编辑器上实时分析。net 代码,它包装了代码分析工具。 它最初是一个 VIM 插件,现在在 Emacs、托架、Atom、Sublime Text、VS Code 和 VIM 上都可以使用。 所有这些代码编辑器都可以在 Windows、macOS 和 Linux 上使用。

omnsharp 链接到你当前的 IDE,它会监视你当前正在工作的项目的文件夹,查询 NuGet,并提供错误检测,但它的主要目标是为 VS 之外的 c#和。net Framework 库提供智能感知。

另请参阅

详见官网:http://www.omnisharp.net/

在 Linux 上安装和使用 omnsharp

在本食谱中,我们将在 Linux 上安装并使用 omnsharp 和 Atom IDE。

准备

对于本食谱,我们将使用 Ubuntu 14.04 VM。 我们必须确保我们遵循了配方三,以确保 Mono、DNVM 和 Kestrel 的 web 服务器已经安装。

怎么做……

  1. 首先,让我们添加一个存储库:
sudo add-apt-get repository ppa:webudp8team/atom
  1. 接下来,我们更新存储库:
sudo apt-get update
  1. 之后,我们安装 Atom:
sudo apt-get install atom
  1. 现在我们可以在命令行中输入atom来启动 Atom:

我们可以看到 Atom 打开如下:

  1. 让我们通过设置|安装来安装 omnsharp 作为一个包。 我们可以根据关键字看到所有可用的包:

  1. omnsharp 正在安装包:

  1. omnsharp 已经完成了它的依赖项的安装:

  1. 我们将能够修改 omnsharp 选项:

  1. 现在,让我们打开一个新项目|ominsharp|新项目:

  1. 当创建一个新项目时,omnsharp 自动恢复应用所需的缺失包:

  1. 现在让我们通过命令行进入应用文件夹来运行应用。

  2. 使用命令dnx web运行应用:

  1. 前面,我们检查了在应用的project.json文件中配置了 web 命令行来运行 Kestrel web 服务器:

  1. 我们可以看到我们的 web 应用运行在http://localhost:5000/:

使用 Roslyn

我们通常认为编译器是一个从输入产生输出的黑盒。 出于速度、自定义内存、文件和线程管理的需要,编译器通常都是用 c++编写的。 例如,c#编译器在输入中获取.cs文件,在输出中生成.dll文件。

现在新的微软编译器用 c#和 VB 编写,Roslyn,不仅仅是一个编译器; 它是一个我们可以扩展的。net 编译平台。

准备

学习使用所有 Roslyn api 可能是整本书的主题。 在本菜谱中,我们将只操作其中一个 API:语法树 API。 我们将创建一个语法树并对其进行分析。

怎么做……

  1. 让我们下载 SDK 并扩展编译器,安装 VS 扩展,.NET 编译器平台 SDK,通过通过 Tools |扩展和更新菜单,搜索 Roslyn SDK:

  1. 现在,我们可以下载。net Compiler Platform SDK 模板作为.vsix文件,它为我们提供了所有可用的项目模板来创建分析器:

  1. 我们现在可以在 New Project | Visual c# | Extensibility |单机代码分析工具中使用模板项目。

  2. 让我们为一个可扩展性项目打开一个新的控制台应用:

这个控制台应用将访问 Roslyn API,通过 Roslyn API,我们可以使用语法树 API。

  1. 现在让我们创建一个SyntaxTree,它是一个简单的类,由使用SyntaxTree类型的元素树结构表示:

该类型有一个名为ParseText的方法,它将解析写入类的字符串:

  1. 让我们来写这段代码:

GetRoot方法将给我们树的根。

  1. 使用Ctrl+F5,我们可以看到结果。
  2. 现在,感谢SyntaxFactory类型,让我们通过SyntaxAPI 创建SyntaxTree来创建相同的类:

  1. 使用SyntaxFactory.ClassDeclaration方法,我们创建类名:

  1. WithMembers方法允许我们创建该类的成员:

  1. 现在我们创建一个名为Bar的方法,以void作为返回类型。
  2. WithBody方法及其参数SyntaxFactory.Block帮助我们向Bar方法添加一个空块:

  1. NormalizeWithespace方法将添加缩进和空格以使该类更具可读性:

  1. 让我们按下Ctrl+F5来查看代码的结果,将表示语法树的变量作为Console.WriteLine的参数:

它是如何工作的…

Roslyn 是开源的,和 TypeScript 编译器一样。 让编译器用我们分析和编译的同一种语言编写的原因之一,是为了享受。net 框架的好处; 例如,在当前窗口中使用lambdasLINQ。 另一个优点是可以使用 ILSpy 之类的工具查看所有编译器代码。

现在,我们可以通过 API 访问编译器的所有阶段,这允许我们操作一个对象模型,该模型表示我们正在分析的作为语法树的源代码。 通过这些 api,我们可以访问一组丰富的语言服务,并将它们集成到编辑器中。

api

编译器内部的组件如下:

  • 解析器
  • 符号和元数据导入
  • 粘结剂
  • 他 emitter

对于管道中的每个组件,我们现在都有一组编译器 api 可以使用:

  • 解析器:语法树 API
  • 对于符号和元数据导入:Symbol API
  • 对于绑定器:绑定和流分析 api
  • 对于 IL 发射器:Emit API

我们还有工作区、诊断 api 和脚本 api。

使用 c# 6 的新特性

在本文中,我们将发现 c# 6 中的一些新特性。

怎么做……

  1. 属性的自动初始化器:

在 c# 6 之前,我们应该用类构造函数中的值来初始化属性。 在类构造函数之前没有时间点,所以我们应该使用它。 多亏了 c# 6 语法,我们现在可以在声明行中使用值初始化属性。 不再需要使用构造函数:

public class Person
{
 Public class Name {get;set;}
 Public Person(){
 Name = "Stephane";
 }
}
Public string Name {get;set;} = "Stephane";
  1. 特性双自动初始化静态属性:

自动初始化器也可以应用于静态属性:

Public static string Name {get;set;}
Public static string Name {get;set;} = "Stephane";
  1. 功能 three-read-only 属性:

自动初始化器甚至可以应用于只读属性:

public List SocialNetworks { get; }
public List SocialNetworks { get; } =
new List { "Twitter", "Facebook", "Instagram" };
Dictionary<string, User> Users = new Dictionary<string, User>()
{
 { "root", new User("root") },
 { "baseUser", new User("baseUser")}
};
Dictionary<string, User> Users = new Dictionary<string, User>()
{
 ["root"] = new User("root"),
 ["baseUser"] = new User("baseUser")
};
  1. 功能 four-expression-bodied 成员:

简单函数(只有return语句的函数)现在可以内联编写:

public double GetVAT(int someValue)
{
 return someValue * 1.2;
}
public double GetVAT(int someValue) => someValue * 1.2;
private DateTime timestamp;
public DateTime TimeStampCreated
{
 get
 {
 return timestamp;
 }
}
public DateTime TimeStampCreated => timestamp;
public static string ReadFile(string fileName) =>
Disposable.Using(
() => System.IO.File.OpenText(fileName),
r => r.ReadToEnd());

The previous piece of code highlights a potential problem that already exists in CSharp, since lambda expressions exist.

It is easy to make fun when writing lambda expressions by creating concise code. It is also easy to write unreadable code, especially for those who will have to use this code. Another problem is that this code is hard to debug.

  1. 特性 five-interpolated 字符串:

我们可以在代码中直接引用变量的名称,在包含变量的字符串之前使用美元符号:

var name = "Stephane";
string.Format($"My name is {name}");
  1. 特性 six-null-conditional 运营商:

要返回一个null值,我们可以使用一种新的语法,它允许我们在返回变量之前不声明null:

var username = (User != null) ? User.Name : string.empty;
var username = User?.Name;

参见……

c# 6 的新特性:http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx

c# 6 中的新语言特性:https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6

插入字符串:https://msdn.microsoft.com/en-us/library/dn961160.aspx

空条件操作符:https://msdn.microsoft.com/en-us/library/dn986595.aspx