zoukankan      html  css  js  c++  java
  • VS中的Code Snippet来提高开发效率


    谈谈VS中的模板中, 我介绍了如何创建项目/项模板,这种方式可以在创建项目时省却不少重复性的工作,从而提高开发效率。在创建好了项目和文件后,就得开始具体的编码了,这时 又有了新的重复性工作,就是需要经常编写一些类似或者说雷同的代码,我们需要一种方法将这些代码管理起来,减少重复输入。

    一个常见的例子,在使用for语句结构时,可能会有这样的代码:
    Code
    int[] array = { 12345 };
    for (int i = 0; i < array.Length; i++)
    {
        Console.WriteLine(array[i]);
    }


    或者

    Code
    List<string> names = new List<string> { "Anders""Bill""Clark""David"};
    for (int i = 0; i < names.Count; i++)
    {
        
    if (names[i].StartsWith("A"))
        {
            Console.WriteLine(names[i]);
        }
    }


    显然,这两个for循环的代码很相似:输入for,选择一个变量用作索引,该变量有个上限值,还有几个括号和分号。而且绝大多数的for循环都是 如此,那么该如何减少重复输入呢? 可以想到的一种方法是把一段for循环的代码保存在某个地方,比如一个文件内,在需要for的地方,拷贝进来,把变量名、初始值、上限修改一下就可以用 了。

    VS的开发者想的很周全,提供了Code Snippet功能,从而实现了上面的想法。它保存了for循环代码的模板,然后给它一个快捷键for。现在在编辑器中(需要是C#文件),输入for,连续按两下Tab键,就会出现下面的代码:


    不 仅有了for的基本代码,还定位到了变量的名字处,如果需要可以修改变量名,假设改为index,后面的两个i会自动改为index,然后按Tab,光标 会跳至下一个深色显示的地方,即length,这里可以修改index的上限,然后回车,光标会跳至for循环的代码体:


    是不是很方便呢?还有很多其它Snippet,比如输入cw,按两下Tab就出来Console.WriteLine()。

    很多时候,同样的功能在不同语言内的表现是不同的,所以Code Snippet(以下简称Snippet)是特定于语言的,也就是说C#的Snippet不能用于VB.NET。VS2008中的Snippet支持C#、VB.NET、XML。

    Snippet的管理

    首 先VS2008提供了很多内置的Snippet,另外我们也可以将自己编写的或者他人编写的导入VS中。通过菜单Tools -> Code Snippets Manager(或按Ctrl+K, Ctrl+B),打开Code Snippets Manager窗口:


    可以看到上面的Language列表,现在选中的是C#。可以通过Import方式来导入新的Snippet。在使用NUnit时,由于测试代码的特点,会有很多重复输入,所以Scott Bellware提供了NUnit的Snippet,我把它放在自己的博客来了:BellwareNUnitSnippet。现在把包里的.snippet文件导入。


    嗯,可以使用了。比如,输入tc,按两下Tab,出来的代码是这样的:


    输入TestCase的名称,回车,这样就可以输入测试代码了。观察一下这个Snippet,它的变化之处只有一个,就是TestCase处。

    接下来我们来分析一下Snippet文件的结构,这样才能编写自己的Snippet。

    Snippet定义文件解析

    下 面来看看Snippet是如何实现的。根据上面tc的例子,我们可以猜想要存放Snippet,至少需要模板代码、占位符、语言类型、快捷键这几个关键信 息,每个Snippet都是如此。事实上,VS把这些信息保存在XML文件中,这些信息都对应着某些节点,这个与上一篇里的模板清单文件类似。

    存放Snippet的文件是XML文件,不过它的扩展名是.snippet。一个Snippet文件可以包含多个Snippet,就像上面的BellwareNUnit.snippet那样。它的基本结构如下:

    XML Code
    <?xml version="1.0" encoding="utf-8" ?>
    <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
        
    <CodeSnippet Format="1.0.0">
            
    <Header>
                
    <Title>Code Snippet for Debug.WriteLine method.</Title>
                
    <Shortcut>dw</Shortcut>
                
    <Author>Anders Cui</Author>
            
    </Header>
            
    <Snippet>
                
    <Code Language="CSharp">
                    
    <![CDATA[
                    Debug.WriteLine(“Text”);
                    
    ]]>
                
    </Code>
            
    </Snippet>
        
    </CodeSnippet>
        
    <!-- other snippets -->
    </CodeSnippets>


    现在新建一个XML文件,输入上面的代码,这里我们的Snippet是输入Debug.WriteLine代码。该文件的根节点为 CodeSnippets,可以包含多个<CodeSnippet>节点。注意它的命名空间,有了这个,在VS内编辑时就方便多了。

    重点关注<CodeSnippet>节点,它即表示一条Snippet。它必须包含一个Format Attribute(老是看到Attribute和Property的讨论,故在此保留),用以表示Snippet版本。另外它必须包含两个子节点:<Header><Snippet>

    对 于<Header>节点,最重要的是Title和Shortcut,即Snippet的名称和快捷键;另外还有SnippetTypes,它 可以包含若干个SnippetType节点,可有三种取值,Expansion、SurroundsWith、Refactoring。 Expansion允许代码插入在光标处;SurroundsWith允许代码围绕在选中代码两边(就像#region那样);Refactoring指 定了在C#重构过程中所使用的Snippet,在自定义Snippet中不能使用。如果该值不做设置,则Snippet可以放在任何地方。

    要了解<Header>的更多信息,请参看这里

    对于<Snippet>节点,它是实现代码模板的地方。它包含四个子节点。

    1、 <Code>节点

    • Delimiter:分隔符,默认值为$,后面你会看到它的用法。
    • Kind:Snippet的类型,比如方法体、方法声明、类型声明等。
    • Language:所适用的语言类型,如C#、VB.NET、XML。

    在我们上面的例子中,已经有了Code节点了,注意这里把代码包含在<![CDATA[]]>中,因为代码很可能会包含一些特殊字符。

    在上面的tc Snippet中,按下Tab后,VS会选中TestCase,这样修改起来更为方便,对于上面的dw Snippet,我们自然希望VS选中”Text”部分,这需要下面的<Declarations>节点。

    2、<Declarations>节点

    该节点包含若干个<Literal>和<Object>节点。它们可以看作是占位符。<Literal>用于指定一些文本值,<Object>则用于声明模板中的对象。
    详细信息请参看<Literal><Object>

    这里需要把”Text”看作占位符,所以添加一个<Literal>节点:

    XML Code
        <Snippet>
            
    <Code Language="CSharp">
                
    <![CDATA[
                Debug.WriteLine($text$);$end$
                
    ]]>
            
    </Code>
            
    <Declarations>
                
    <Literal>
                    
    <ID>text</ID>
                    
    <ToolTip>Text to write</ToolTip>
                    
    <Default>"Text"</Default>
                
    </Literal>
            
    </Declarations>
        
    </Snippet>


    这里添加了一个占位符$text$,默认值为”Text”,行末的$end$是一个特殊的占位符,它表示当你按下回车后光标的位置

    3. <Imports>节点

    用于指定使用Snippet时应当向文件内添加的命名空间引用,不过只支持VB.NET。

    4. <References>节点

    用于指定使用Snippet时应当向添加的程序集引用,同样只支持VB.NET:(

    好了,现在可以测试一下我们的Snippet了,将文件保存为.snippet文件,然后导入。

     
    还不错吧?

    Code Snippet 函数

    前面说到,<Imports>和<References>节点只能用于VB.NET,而这里的Code Snippet函数则只能用于C#。

    在<Literal>和<Object>节点中,都包含了子节点<Function>,这些函数是VS的一部分,有时会比较有用。共有三个函数:

    1. GenerateSwitchCases(EnumerationLiteral),根据提供的枚举类型生成一个switch语句和一系列case语句,事实上,C#中已有这样的一个例子:

    回车确认:


    2. ClassName(),返回Snippet所在类的名称。

    3. SimpleTypeName(TypeName),在Snippet所在的上下文中推断出TypeName参数的最简单形式。
    下面以SimpleTypeName为例来看一下这些函数的用法:

    XML Code
    <Snippet>
        
    <Code Language="CSharp">
        
    <![CDATA[
        $NameOfDebug$.WriteLine($text$);$end$
        
    ]]>
        
    </Code>
        
    <Declarations>
            
    <Literal>
                
    <ID>text</ID>
                
    <ToolTip>Text to write</ToolTip>
                
    <Default>"Text"</Default>
            
    </Literal>
            
    <Literal Editable="false">
                
    <ID>NameOfDebug</ID>
                
    <Function>SimpleTypeName(global::System.Diagnostics.Debug)</Function>
            
    </Literal>
        
    </Declarations>
    </Snippet>


    这里比前面的Snippet添加了一个Literal,为什么需要这么做呢?我们知道System.Diagnostics命名空间默认情 况下是没有引用的,如果使用Debug类,还需要引用System.Diagnostics。这里的妙处在于VS会推断NameOfDebug的最简单形 式,如果没有引用System.Diagnostics,它会在Debug前面加上,否则就不会加上。

    几条建议

    首先,Snippet的定义都在XML中,因此也算得上是代码,所以在命名上与其它代码无异,都要选择更有意义或者相关性的名字。命名快捷键的一个做法是使用首字母的缩写,比如Assert.AreEqual(expected, actual);的快捷键为ae。

    另外,记得填写ToolTip节点的内容,这些内容在使用Snippet时会看到。

    其它工具


    虽然Snippet可以简化代码输入,可是它本身的编写却并非很方便,使用一些可视化工具会更好,比如Snippet Editor,有兴趣可以试一下。

    另外,这个世界还有很多人在编写Snippet,比如gotcodesnippets.com,所以在动手编写之前可以先搜索一下:)

    小结

    本文介绍了Code Snippet的使用和编写,它可以看作是代码片段的模板,在粒度上比项目/项模板更小,从而进一步提高了工作效率。

    参考

    《Professional Visual Studio® 2008 Extensibility》

  • 相关阅读:
    Nim or not Nim? hdu3032 SG值打表找规律
    Maximum 贪心
    The Super Powers
    LCM Cardinality 暴力
    Longge's problem poj2480 欧拉函数,gcd
    GCD hdu2588
    Perfect Pth Powers poj1730
    6656 Watching the Kangaroo
    yield 小用
    wpf DropDownButton 源码
  • 原文地址:https://www.cnblogs.com/tonybinlj/p/1562699.html
Copyright © 2011-2022 走看看