在开发的项目的时候,你是否经常遇到需要重复编写一些类似的代码,比如是否经常会使用 for、foreach ? 在编写这两个循环语句的时候,你是一个字符一个字符敲还是使用 Visual Studio 提供的Code Snippet 工具自动帮你生成呢?

神奇之处

  你只需要在代码编辑器中输入for,就会看到 Visual Studio 的自动提示框中出现了如下红框框起来的部分,这个时候只需要连按两下 tab 键,便会自动补全 for 循环语句(如图2所示),并且默认选中索引,以便你进行修改。

图 1  自动提示框

图 2  自动补全循环语句

  是不是很神奇? 与之类似的还有switch、cw (Console.WriteLine)、ctor(构造器)、prop(属性)等,灵活运用这些就可以让你的 Coding 工作事半功倍,更多默认 CodeSnippet 请查看参考资源[1]

  但是,每个项目都有每个项目的特殊性,默认的这些 Code Snippet 如果无法满足您的需求,这个时候就需要自动动手来扩展了。

Code Snippet 的神秘面纱【C#】

  在动手开始写自己的 Code Snippet 之前,得先搞清楚这个玩意儿是怎么做到的。

  它其实只是一个 xml,只不过包含了一些只有 Visual Studio 才认识的元素,这些元素就定义了如何去替我们补全代码(,Code Snippet 针对不同的语言如VB、C#、CSS使用不同的元素,本文全部按照 C# 语言进行介绍)。

  下面来看一下 for 的Snippet源代码是长什么样子的

 <?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>for</Title>
<Shortcut>for</Shortcut>
<Description>for 循环的代码段</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
<SnippetType>SurroundsWith</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>index</ID>
<Default>i</Default>
<ToolTip>索引</ToolTip>
</Literal>
<Literal>
<ID>max</ID>
<Default>length</Default>
<ToolTip>最大长度</ToolTip>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[for (int $index$ = 0; $index$ < $max$; $index$++)
{
$selected$ $end$
}]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

  一个 CodeSnippet 则主要包含 <Header> 和 <Snippet> 两部分。上面的结构挺清晰的,一个 <CodeSnippets> 元素可以包含多个不同的 <CodeSnippet> 。

  其中 <Header> 部分主要是对这个 Snippet 的一个声明,包括 Snippet 的名称、描述、作者及 Snippet 的类型(稍后会解释)。

Header 部分在实际运行中的作用

<Snippet> 元素

  snippet元素是关键的重点,单独弄一节来具体说明。

  完整的 snippet 元素结构如下:

 <Snippet>
<Declarations>... </Declarations>
<Code>... </Code>
</Snippet>

  <Declarations> 元素

  该元素用于定义在运行中需要被替换的变量,Microsoft 提供了两种类型:Literal(文本)和 Object(对象)。MSDN上的解释如下:

Literal 元素用于标识整体包含在代码段中、但在插入到代码中后可能会进行自定义的代码部分的替换对象。例如,字符串、数字值以及应声明为文本的一些变量名。

Object 元素用于标识代码段所需的、但可能是在代码段外部定义的项。例如,Windows 窗体控件、ASP.NET 控件、对象实例以及类型实例应声明为对象。对象声明需要指定类型。

  至于这两者在实际运用中的区别,我还真不清楚。如果哪位大侠对此了解,还望指点一二。下面只介绍 Literal 类型。

  完整的 <Literal> 结构如下:

 <Literal Editable="true/false">
<ID>... </ID>
<ToolTip>... </ToolTip>
<Default>... </Default>
<Function>... </Function>
</Literal>

  ID 用于指定需要被替换的对象名称,有且只有一个。Editable 意味在生成代码过程中能不能直接替换成我们想要文本,比如 for 循环中的索引变量,默认是 “i”,但是我们可以替换成任何自己想要的,比如 “Index”。

  Default 表示默认生成代码时,该对象将被 Default 值给代替。

  Function 指示当该对象在获取焦点的时候将要执行的方法。在 Visual Studio 中目前只支持三个方法:GenerateSwitchCases(EnumerationLiteral)、ClassName()、SimpleTypeName(TypeName)。

  其中 GenerateSwitchCases 顾名思义是用于为switch的变量生成case条件的。

  ClassName方法用于获取当前的类名。

  SimpleTypeName 则用于缩短类型的名字,因为有些时候有些程序集不会被using进来,这个时候对该程序集中某一类型的调用就需要使用 “名称空间.类型名称” 这种方式。但是如果当前的文件已经把需要的程序集using进来了,那这种调用方式就显得是多此一举。通过使用 SimpleTypeName 就能在生成代码的时候帮助我们判断是否需要加上名称空间这个前缀。

  <Code> 元素

  这才是我们的主角,因为我们的代码就是写在了该元素内部。先来看一个例子:

 <Code Language="csharp"><![CDATA[for (int $index$ = 0; $index$ < $max$; $index$++)
{
$selected$ $end$
}]]>

  上面的代码相当简单,所有需要在生成代码的时候被替换的内容都用 $ 包裹,如$index$,记住这个被包裹的内容必须在 <Declarations> 被正确定义过。因为代码中可能会有一些在XML中有特殊含义的字符,所以用CDATA进行包裹,防止错误转义。

  $selected$ 和 $end$ 是保留的关键字,其中 $end$ 用于指示当代码插入完毕后,光标应该位于的位置。$selected$ 用于表示在生成代码前你所选中的文本,并在生成代码的过程中使用你选中的文本替换 $selected$,常用于 SurroundWith 这种类型的 Code Snippet 中。

Snippet 类型

  根据我们的使用方式,snippet 分为 ExpansionSurroundsWith 及 Refactoring(只能在重构过程中使用,自定义的 Code Snippet 不能使用)。

  Expansion:允许将代码段插入到光标处。

  SurroundsWith:允许将此代码段放置在一段选定的代码周围。比如我们写完一段代码后,发现忘记加 try...catch... 了,这个时候可以选中需要包裹在 try...catch... 中的代码,然后调用 Code Snippet。

如何自定义一个 snippet

  如果对上面的结构有了基本了解,下面就来实践一下吧。通过本节,我们要实现自动生成 Debug.WriteLine 的 snippet。

  首先,打开 Visual Stuido / 文件 / 新建 / 文件,选择 xml 类型。

  在 xml 文件中,输入最小的snippet代码。

 <?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title></Title>
</Header>
<Snippet>
<Code Language="">
<![CDATA[]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

  

  修改如上的代码,包括 Header 部分和 Snippet 部分,别忘记指定Language。

 <?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>dw</Title>
<Description>Debug.WriteLine</Description>
<Shortcut>dw</Shortcut>
<Author>Charley</Author>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>text</ID>
<ToolTip>希望输出的内容</ToolTip>
<Default>"text"</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[Debug.WriteLine($text$);$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

  如果嫌自己写太麻烦,也可以使用开源的 snippet 编辑工具,详见参考资源[2]

Snippet 的管理

  新建完一个snippet之后,该如何才能在项目中用起来呢?

  工具 / 代码段管理器 打开管理器。

  使用 “导入” 将自定义的文件导入进来。

  为自己的 snippet 选择一个位置。

  点击完成就已经成功了。在代码编辑器中,输入 dw 就会发现 Visual Stuido 的智能提示已经出现了我们的 snippet。

如何使用 SurroundWith 类型的 Snippet?

  相比于 Expansion 类型的 snippet,使用 SurroundsWith 相对要麻烦点

本人认为最快捷的方式就是使用键盘快捷键,在代码编辑器中 CTRL+K, CTRL+S,就可以呼出 snippet。

  然后用键盘或鼠标选择目标 snippet。

参考资源

  [1] Visual C# Code Snippets

  [2] Snippet Editor

  本文来源于 《使用 Code Snippet 简化 Coding》

使用 Code Snippet 简化 Coding的更多相关文章

  1. C# 使用 Code Snippet 简化 Coding

    在开发的项目的时候,你是否经常遇到需要重复编写一些类似的代码,比如是否经常会使用 for.foreach ? 在编写这两个循环语句的时候,你是一个字符一个字符敲还是使用 Visual Studio 提 ...

  2. [Note] 使用Code Snippet简化编码

    使用NewtonSoft.Json写实体类时大量格式一致的代码出现 ,这时可以使用Code snippet来加快编码速度 [JsonProperty(PropertyName = "mess ...

  3. Visual Studio 如何使用代码片段Code Snippet提高编程速度!!!

      使用Code Snippet简化Coding 在开发的项目的时候,你是否经常遇到需要重复编写一些类似的代码,比如是否经常会使用 for.foreach ? 在编写这两个循环语句的时候,你是一个字符 ...

  4. 善用VS中的Code Snippet来提高开发效率

    http://www.cnblogs.com/anderslly/archive/2009/02/16/vs2008-code-snippets.html http://www.cnblogs.com ...

  5. 善用VS中的Code Snippet来提高开发效率 分类: C# 2015-01-22 11:06 69人阅读 评论(0) 收藏

    前言  在谈谈VS中的模板中,我介绍了如何创建项目/项模板,这种方式可以在创建项目时省却不少重复性的工作,从而提高开发效率.在创建好了项目和文件后,就得开始具体的编码了,这时又有了新的重复性工作,就是 ...

  6. 创建自己的Code Snippet(代码模板)

    一.名词解释 Code Snippet,代码模板,是一种快速生成代码的快捷方式,使用它可以有效地提高编程效率. 编程中可以使用Visual Studio提供的预先设置好的Code Snippet,也可 ...

  7. Xamarin.Forms XAML的辅助功能Code Snippet

    Xamarin.Forms XAML的辅助功能Code Snippet   在Visual Studio中,使用Code Snippet(代码片段)功能可以减少基础代码的编写量,如常见的标签.循环语句 ...

  8. 如何创建 Code Snippet

    比如有一行自定义代码段: @property (nonatomic,copy) NSString *<#string#>; 需要添加到 Code Snippet 上,以帮助开发人员开发更便 ...

  9. 介绍 .Net工具Code Snippet 与 Sql Server2008工具SSMS Tools Pack

    不久前,某某在微软写了一个很酷的工具:Visual Stuido2008可视化代码片断工具,这个工具可以在http://www.codeplex.com/SnippetDesigner上免费下载,用它 ...

随机推荐

  1. 开源:Taurus.MVC 框架

    为什么要创造Taurus.MVC: 记得被上一家公司忽悠去负责公司电商平台的时候,情况是这样的: 项目原版是外包给第三方的,使用:WebForm+NHibernate,代码不堪入目,Bug无限,经常点 ...

  2. Taurus.MVC 2.0 开源发布:WebAPI开发教程

    背景: 有用户反映,Tausus.MVC 能写WebAPI么? 能! 教程呢? 嗯,木有! 好吧,刚好2.0出来,就带上WEBAPI教程了! 开源地址: https://github.com/cyq1 ...

  3. Javascript生成二维码(QR)

    网络上已经有非常多的二维码编码和解码工具和代码,很多都是服务器端的,也就是说需要一台服务器才能提供二维码的生成.本着对服务器性能的考虑,这种小事情都让服务器去做,感觉对不住服务器,尤其是对于大流量的网 ...

  4. Angular企业级开发(3)-Angular MVC实现

    1.MVC介绍 Model-View-Controller 在20世纪80年代为程序语言Smalltalk发明的一种软件架构.MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并 ...

  5. MySQL主从环境下存储过程,函数,触发器,事件的复制情况

    下面,主要是验证在MySQL主从复制环境下,存储过程,函数,触发器,事件的复制情况,这些确实会让人混淆. 首先,创建一张测试表 mysql),age int); Query OK, rows affe ...

  6. 前端MVC学习总结(一)——MVC概要与angular概要、模板与数据绑定

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.AngularJS是框架而jQuery则是库. 1.2. ...

  7. Spring中Bean的实例化

                                    Spring中Bean的实例化 在介绍Bean的三种实例化的方式之前,我们首先需要介绍一下什么是Bean,以及Bean的配置方式. 如果 ...

  8. js报错: Uncaught RangeError: Invalid string length

    在ajax请求后得到的json数据,遍历的时候chrome控制台报这个错误:Uncaught RangeError: Invalid string length,在stackoverflow查找答案时 ...

  9. MFC中成员变量的声明顺序与析构顺序

    第一次用博客,第一篇随笔,就写今天遇到的一个问题吧. 在VS2008的MFC对话框程序,窗口成员变量的声明顺序与其析构顺序相反,即,先声明的变量后析构,后声明的变量先析构.未在其他模式下测试. cla ...

  10. 使用po模式读取豆瓣读书最受关注的书籍,取出标题、评分、评论、题材 按评分从小到大排序并输出到txt文件中

    #coding=utf-8from time import sleepimport unittestfrom selenium import webdriverfrom selenium.webdri ...