zoukankan      html  css  js  c++  java
  • VS2010中自定义CodeSnippet【自定义代码段】创建与应用

    内容概要:

    1. 什么是Code Snippet?它能为我们带来什么?
    2. 如何使用Code Snippet?
    3. 分析Code Snippet文件【.snippet】
    4. 编写一个实现属性更改通知的Code Snippet

    什么是Code Snippet?它能为我们带来什么?

    Code Snippet是预编写的代码片段,您可以随时使用 Visual Studio 将这些代码片段插入到您的应用程序中。这些代码段减少了键入重复代码或搜索示例所用的时间,从而提高了工作效率。可以使用代码段 XML 架构创建自己的 Visual Basic、Visual C# 或 XML 代码段,并将它们添加到 Visual Studio 已包含的代码段中。【来自MSDN】

    如何使用Code Snippet?

    1. 首先 ,新建一个控制台应用程序“CodeSnippetExample”
    2. 在Program类内部,Main方法外部敲入“prop”(property,“属性”的缩写)
    3. 在输入完“prop”后,按下“tab”键,你就会发现代码变成了这个样子:

      其中,浅蓝色背景标识着我们正在修改的代码,可以通过按“tab”键来更改修改光标,如果这时按下“tab”键,代码就会变成下面的样子,这样就可以修改“MyProperty”了。
    4. 现在,我们将属性的类型修改为“String”,属性名改为“NewProperty”。
    5. 然后,键入回车键,退出代码段模式,这样,一个简写的属性就完成了。

    这个只是一个简单的例子,同样的,你还可以使用propfull来实现具有字段的属性,比如下面的:

    到现在,可以很明显的看出,如果我们能很好的利用CodeSnippet的话,编写代码的速度将会有很大的提升,比如,我会使用CodeSnippet来帮我编写通知属性,从而少去了大量手工代码的编写:

    在VS中内置了很多现成的CodeSnippet模板,可以通过VS-工具-代码段管理器来查看这些CodeSnippet。

    分析Code Snippet文件【.snippet】

    在代码段管理器中,把“语言”选项调整为“Visual C#”,展开下面的Visual C#节点,就会看到下面的东西:

    下面,把“位置”下面的地址复制到“资源管理器”的地址栏,按回车,并且找到“prop.snippet”,双击它,默认会被VS打开,下面给出代码:

     <CodeSnippet Format="1.0.0">
      <Header>
       <Title>prop</Title>
       <Shortcut>prop</Shortcut>
       <Description>自动实现的属性的代码段
    语言版本: C# 3.0 或更高版本</Description>
       <Author>Microsoft Corporation</Author>
       <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
       </SnippetTypes>
      </Header>
      <Snippet>
       <Declarations>
        <Literal>
         <ID>type</ID>
         <ToolTip>属性类型</ToolTip>
         <Default>int</Default>
        </Literal>
        <Literal>
         <ID>property</ID>
         <ToolTip>属性名</ToolTip>
         <Default>MyProperty</Default>
        </Literal>
       </Declarations>
       <Code Language="csharp"><![CDATA[public $type$ $property$ { get; set; }$end$]]>
       </Code>
      </Snippet>
     </CodeSnippet>
    </CodeSnippets>

    很明显的,这是一个XML格式的文件,其根节点CodeSnippets下有一个CodeSnippet节点,代表一个CodeSnippet代码段。在CodeSnippet节点下面,有两个节点,Header和Snippet。

    先分析Header。在Header下有下面几个标签:Title,Shortcut,Description,Author,SnippetTypes。前4个标签都很好理解,分别是:标题,快捷命令,描述,作者。难理解的是最后一个:SnippetTypes。

    SnippetTypes,指定 Visual Studio 如何将代码段插入到代码中。SnippetTypes 元素中可能有零个或多个 SnippetType 元素。 <?XML:NAMESPACE PREFIX = [default] http://msdn2.microsoft.com/mtps NS = "http://msdn2.microsoft.com/mtps" /?> 如果 SnippetTypes 元素不存在,则代码段可以插入到代码中的任何位置。 其子节点只能为SnippetType,且SnippetType只能有两种值:SurroundsWith(允许将此代码段放置在一段选定的代码周围)、Expansion(允许将代码段插入到光标处。 )。这个不是很理解。。。

    下面,开始分析Snippet。在Snippet下面有两个标签Declarations(声明),Code。

    Declarations:指定构成代码段可编辑部分的文本和对象。

    在Declarations标签内部的Literal定义代码段的可编辑文本。Literal元素用于标识完全包含在代码段中的代码片段替换,不过这些代码片段在插入到代码中后,可能需要进行自定义。 例如,字符串、数值和一些变量名都应声明为文本。(这个是MSDN中的解释,说白了就是定义我们在使用CodeSnippet时可以编辑的几个部分,想象成模板替换符也可以)

    在Literal标签下,有三个标签,ID(必选的,用于模板替换时的标识符),ToolTip(可选的,提示文本),Default(必选的,指定插入代码段时文本的默认值。也就是模板替换符的默认值)。

    结束了”定义部分“,我们就要组织模板了。开始分析Code标签。

    Code标签中的内容很简单,使用XML属性标识了使用的语言是csharp,其内部的数据标签,就是一个代码模板,这里便用上了上面定义的Declarations,用法很简单,在ID前后加$符号就可以。

    【PS】分析的不好,大家见谅。。。

    编写一个实现属性更改通知的Code Snippet

    在WPF程序中,有很多程序员乐于使用MVVM模式,于是,在写ViewMode时,编写具体有通知功能的属性就成了这部分程序员必须做的事情,他们写出的代码大概就是这样:

        public class ViewModel : NotificationObject
        {
            private String userName;
            public String UserName
            {
                get { return userName; }
                set { userName = value; this.RaisePropertyChanged("UserName"); }
            }
        }

    仔细观察,发现这段代码中声明UserName属性的代码,其代码和使用propfull生成的代码很相似,只不过是在set访问器中多了一句this.RaisePropertyChanged("UserName"); 而已。现在,开始让代码简化起来。。。

    首先,找到propfull的CodeSnippet文件,复制到桌面。:C:Program FilesMicrosoft Visual Studio 10.0VC#Snippets2052Visual C#propfull.snippet

    修改Title,Shortcut,Description。。。。propNotification,propno,具有通知功能的属性。

    接着,在Code标签中找到set访问器的代码,在其原有语句的分号后面加上这句话:“this.RaisePropertyChanged("$property$");”。

    这样,一个实现通知同能属性的CodeSnippet就写好了。然后把这个文件保存,重命名为propn.snippet 复制到C:Program FilesMicrosoft Visual Studio 10.0VC#Snippets2052Visual C#目录,重启VS,试试看,是不是成功了?

    出处:https://www.cnblogs.com/Soar1991/archive/2012/03/26/2418748.html

    ====================================================================================

    前言

    谈谈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([Math Processing Error]text );[Math Processing Error]end
                
    ]]>
            
    </Code>
            
    <Declarations>
                
    <Literal>
                    
    <ID>text</ID>
                    
    <ToolTip>Text to write</ToolTip>
                    
    <Default>"Text"</Default>
                
    </Literal>
            
    </Declarations>
        
    </Snippet>
    复制代码


    这里添加了一个占位符[Math Processing Error]text ,默认值为”Text”,行末的[Math Processing Error]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[
        [Math Processing Error]NameOfDebug .WriteLine([Math Processing Error]text );[Math Processing Error]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》

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

  • 相关阅读:
    MongoDB驱动之Linq操作
    连接Access数据库
    ExecutorCompletionService原理具体解释
    Java 构造时成员初始化的陷阱
    activeMQ公布订阅模式中中经常使用工具类
    计算机视觉、图像处理一些先进研究机构
    php循环,die/exit脚本执行控制,文件载入及错误控制
    VCenter中嵌套openstack VM不能ping通外部网络问题解决的方法
    代码保存、配色、公布-总体方案----一段代码的公布
    【iOS开发系列】NSObject方法介绍
  • 原文地址:https://www.cnblogs.com/mq0036/p/12957100.html
Copyright © 2011-2022 走看看