Visual Studio 自定义代码块

257 阅读4分钟

1. 简介

代码片段(Code Snippet)是 Visual Studio 中一项极其强大的功能,它允许开发者将预定义的可复用代码块通过一个简短的“快捷词”快速插入到编辑器中。自定义代码片段不仅能大幅提升编码效率,还能确保团队代码风格的统一性和规范性。

2. 快速上手:创建你的第一个代码片段

我们先从一个简单的例子开始:创建一个快捷方式 ps 来生成 public string MyProperty { get; set; }。

步骤一:打开代码段管理器

在 Visual Studio 顶部菜单栏中,选择 工具 (Tools) > 代码段管理器 (Code Snippets Manager) (快捷键: Ctrl + K, Ctrl + B)。

image.png

步骤二:定位代码片段文件夹

在代码段管理器中,语言 (Language) 选择 CSharp。

在列表中找到并选中 My Code Snippets。

image.png

复制其 位置 (Location) 框中的文件夹路径,并在文件资源管理器中打开它。

步骤三:创建并编写 .snippet 文件

在该文件夹中,新建一个文本文档,命名为 my-first-snippet.snippet。

用文本编辑器打开它,并粘贴以下内容:

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Public String Property</Title>
            <Shortcut>ps</Shortcut>
            <Description>快速创建一个 public string 类型的自动属性。</Description>
            <Author>Your Name</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>propname</ID>
                    <ToolTip>属性的名称</ToolTip>
                    <Default>MyProperty</Default>
                </Literal>
            </Declarations>
            <Code Language="CSharp">
                <![CDATA[public string $propname$ { get; set; }$end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

image.png

步骤四:使用你的代码片段

保存文件。Visual Studio 会自动加载新的代码片段。

在任何 .cs 文件的类中,输入 ps,然后连续按两次 Tab 键。

代码将自动生成,MyProperty 会被高亮,您可以直接输入新的属性名,然后按回车完成。

3. Snippet 文件结构深度解析

.snippet 文件是一个 XML 文件,其核心结构如下:

<CodeSnippets>: 根元素,可以包含一个或多个 <CodeSnippet> 定义。

<CodeSnippet>: 定义单个代码片段,包含 <Header> 和 <Snippet> 两个部分。

3.1 <Header> 元素:元数据

定义代码片段的描述信息。

字段是否必需功能描述
<Title>代码片段的标题,显示在选择器列表中。
<Shortcut>核心字段。触发代码片段的快捷词。
<Description>对功能的详细描述。
<SnippetTypes>定义片段类型,最常用的为 Expansion(在光标处插入)和 SurroundsWith(包裹选中代码)。

3.2 <Snippet> 元素:核心逻辑

定义代码片段的实际内容和行为。

字段功能描述
<Declarations>(可选)核心字段。在此声明可替换的文本(Literal)或对象(Object),实现代码的动态化。
<Code>必需)包含将要插入的实际代码,并引用在 Declarations 中定义的变量。

<Declarations> 中的 <Literal> 详解:

  • <ID>: 变量的唯一ID,在 <Code> 块中通过 $ID$ 的形式引用。

  • <ToolTip>: 当用户编辑此变量时显示的提示信息。

  • <Default>: 变量的默认值。

<Code> 中的特殊变量:

  • $ID$: 替换为声明的同名变量值。

  • $selected$: 仅用于 SurroundsWith 类型,代表用户选中的代码。

  • $end$: 代码生成和编辑完成后,光标最终停留的位置。

4. 进阶技巧:将多个片段整合到单个文件

这是一个非常高效的最佳实践。您可以将所有功能相关的代码片段(如各种类型的属性、各种循环)都定义在同一个 .snippet 文件中,便于统一管理和分发。

其结构非常简单,只需在 根节点下并列放置多个 节点即可。

5. 可直接使用的模板与实例

以下是根据最佳实践整理的、功能丰富的代码片段文件。您只需将它们保存到您的代码片段文件夹中即可使用。

示例一:整合多种类型的属性定义 (prop-types.snippet)

这个文件包含了多种常用数据类型的属性快捷方式,是实体类开发的利器。

文件名建议: prop-types.snippet

适用语言: CSharp

包含快捷词: ps (string), pi (int), pb (bool), pd (double), pdt (DateTime)

    <?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">

    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Public String Property</Title>
            <Shortcut>ps</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>propname</ID><ToolTip>属性名称</ToolTip><Default>MyProperty</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[public string $propname$ { get; set; }$end$]]></Code>
        </Snippet>
    </CodeSnippet>

    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Public Int Property</Title>
            <Shortcut>pi</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>propname</ID><ToolTip>属性名称</ToolTip><Default>MyProperty</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[public int $propname$ { get; set; }$end$]]></Code>
        </Snippet>
    </CodeSnippet>

    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Public Bool Property</Title>
            <Shortcut>pb</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>propname</ID><ToolTip>属性名称</ToolTip><Default>MyProperty</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[public bool $propname$ { get; set; }$end$]]></Code>
        </Snippet>
    </CodeSnippet>

    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Public Double Property</Title>
            <Shortcut>pd</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>propname</ID><ToolTip>属性名称</ToolTip><Default>MyProperty</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[public double $propname$ { get; set; }$end$]]></Code>
        </Snippet>
    </CodeSnippet>
    
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Public DateTime Property</Title>
            <Shortcut>pdt</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>propname</ID><ToolTip>属性名称</ToolTip><Default>MyProperty</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[public DateTime $propname$ { get; set; }$end$]]></Code>
        </Snippet>
    </CodeSnippet>

</CodeSnippets>

示例二:整合多种循环结构 (loops.snippet)

这个文件包含了标准循环以及一个非常实用的自定义反向 for 循环 (forr)。

文件名建议: loops.snippet

适用语言: CSharp

包含快捷词: for, foreach, forr (反向循环)

    <?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">

    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>For Loop</Title>
            <Shortcut>for</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>i</ID><ToolTip>循环计数器</ToolTip><Default>i</Default></Literal>
                <Literal><ID>length</ID><ToolTip>循环的最大长度</ToolTip><Default>length</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[for (int $i$ = 0; $i$ < $length$; $i$++){$end$}]]></Code>
        </Snippet>
    </CodeSnippet>

    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Foreach Loop</Title>
            <Shortcut>foreach</Shortcut>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>item</ID><ToolTip>集合中的元素</ToolTip><Default>item</Default></Literal>
                <Literal><ID>collection</ID><ToolTip>要遍历的集合</ToolTip><Default>collection</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[foreach (var $item$ in $collection$){$end$}]]></Code>
        </Snippet>
    </CodeSnippet>

    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>Reverse For Loop</Title>
            <Shortcut>forr</Shortcut>
            <Description>插入一个反向 for 循环,用于安全地从后向前遍历并操作集合。</Description>
        </Header>
        <Snippet>
            <Declarations>
                <Literal><ID>i</ID><ToolTip>循环计数器</ToolTip><Default>i</Default></Literal>
                <Literal><ID>collection</ID><ToolTip>要反向遍历的集合(数组或列表)</ToolTip><Default>myList</Default></Literal>
            </Declarations>
            <Code Language="CSharp"><![CDATA[for (int $i$ = $collection$.Count - 1; $i$ >= 0; $i$--){$end$}]]></Code>
        </Snippet>
    </CodeSnippet>

</CodeSnippets>

6. 参考资料

官方文档 - 代码片段: learn.microsoft.com/zh-cn/visua…

演练:创建代码片段: learn.microsoft.com/zh-cn/visua…

代码片段架构参考 (Snippet Schema Reference): learn.microsoft.com/zh-cn/visua…