书写Visual Studio代码片段

日之朝矣

在使用 Visual Studio 作为我们的IDE进行开发时,使用如cw等快速生成代码片段Console.WriteLine()能显著的提升我们的编码速度。但随着日常的学习,已有的代码片段已经无法满足我们的需求了,因此这里就来介绍如何简单的创建一个自定义代码片段。

由于本人技术与研究时间问题,且并未通过官方文档找到关于如何获取已编写代码的内容,这里并不能写出复杂的代码片段,如通过ctor生成带有所有成员变量的构造函数。

文章末尾会放几个本人常用的代码片段,需要的可以通过标题查看是否有需要的,直接跳转复制粘贴。

官方文档:代码片段及其使用方法

代码片段

首先我们可以在 Visual Studio 中的 菜单栏 -> 工具 -> 代码片段管理器中,通过筛选编程语言,来找到现有的代码片段。

如我们可以在Visual C#中找到经常使用的classctorcw等。

同时在上面我们可以看到这个代码片段的所在位置,我们后续就通过这些默认的代码片段来书写我们自己的代码片段。

写属于自己的代码片段

这里通过一个简单的例子,来过一下写代码片段的流程,我们的目标是使用cwi生成Console.WriteLine($"{}")这样的含有字符串插值的控制台输出代码片段。

由于代码片段很长,一般会选择使用官方已经写好的代码片段,进行修改,保存使用(官方代码片段文件权限为只读,保存时只能另存为,我们就利用这个方式来拿到模板)。

在代码片段管理器里,通过点击指定的代码片段,我们可以获知这个代码片段的位置。

如我的cw代码片段存储位置:D:\Visual Studio Professional\VC#\Snippets\2052\Visual C#\cw.snippet

在文件资源管理器中找到该代码的位置,直接打开,默认会使用 Visual Studio 打开该文件。

虽然他的后缀名为:.snippet但这还是一份XML格式的文件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>cw</Title>
<Shortcut>cw</Shortcut>
<Description>Console.WriteLine 的代码片段</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal Editable="false">
<ID>SystemConsole</ID>
<Function>SimpleTypeName(global::System.Console)</Function>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[$SystemConsole$.WriteLine($end$);]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

上面的代码分为两个大部分,这两个大部分可含有的信息如下,

Header 部分:包含有关代码段的常规信息。

  • <Title>:可选,必需,代码段的友好名称。
  • <Shrotcut>:可选,指定可用于插入代码段的快捷方式文本。
  • <Description>:可选,代码段说明。
  • <Author>:可选,编写代码段的人员或公司的姓名或名称。
  • <SnippetTypes>:可选。 对 SnippetType 元素进行分组。

Snippet部分:指定代码段的引用、导入、声明和代码。

  • Declarations:可选,指定作为某个代码段组成部分的文本和对象。
  • Code必需 。 指定要插入到文档文件中的代码。
  • Imnports:可选,对单个Import进行分组。
  • References:可选,对单个Reference进行分组

Header部分主要用来放一些关于这个代码段的信息以及代码段的触发文本,我们只需要将<Shrotcut>中的内容修改为我们要使用的快捷文本cwi,标题也改一下。

1
2
3
4
5
6
7
8
9
<Header>
<Title>cwi</Title>
<Shortcut>cwi</Shortcut>
<Description>Console.WriteLine($"{}") 的代码片段</Description>
<Author>RiZhiZhaoYi</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>

Snippet部分就是我们编写代码段重点要操作的部分了。

1
2
3
4
5
6
7
8
9
10
11
12
13
<Snippet>
<!-- 指定作为某个代码段组成部分的文本和对象,你可以对该代码段进行编辑。 -->
<Declarations>
<Literal Editable="false">
<ID>SystemConsole</ID>
<Function>SimpleTypeName(global::System.Console)</Function>
</Literal>
</Declarations>

<!-- 这里写代码片段 -->
<Code Language="csharp"><![CDATA[$SystemConsole$.WriteLine($end$);]]>
</Code>
</Snippet>

简单介绍一下上面的代码,基本上简单的代码片段就能写了。

用通俗的话来说,在<Declarations>中,使用<Literal>来定义变量,<ID>是变量名,<Default>是变量的值也是变量的默认值,<Function>是函数。

比如,我要定义一个名为dollars的变量,值是$这个符号。

1
2
3
4
5
6
7
8
9
10
11
<Declarations>
<!-- Editable 表示是否可修改,改为false后,在生成代码段后,在使用Tab键就不会自动选中并跳到这个值上,方便实用 -->
<Literal Editable="false">
<ID>dollars</ID>
<Default>$</Default>
</Literal>
<Literal Editable="false">
<ID>SystemConsole</ID>
<Function>SimpleTypeName(global::System.Console)</Function>
</Literal>
</Declarations>

<Function>只有三个函数可以使用,例子详见 Function元素

函数说明
GenerateSwitchCases(EnumerationLiteral)EnumerationLiteral 参数指定的枚举成员生成一个switch 语句和一组 case 语句。 该 EnumerationLiteral 参数必须是对枚举文本或枚举类型的引用。
ClassName()返回包含插入的代码片段的类的名称。
SimpleTypeName(TypeName)TypeName 参数减少为调用代码片段的上下文中最简单的形式。

上面的代码片段中,用到了SimpleTypeName()来尽可能简化控制台输出语句的长度。如果没有引入System这个命名空间,则使用cw快速生成的代码片段将是System.Console.WriteLine()

我们定义好 “变量” 后,就该去使用了,到<Code>中去书写我们的代码片段了。

1
<Code Language="csharp"> <![CDATA[]]></Code>

<Code>标签中的Language的值为我们要书写的代码片段要使用在哪个编程语言中。

<![CDATA[]]>标签中,最内层的[]位置就是我们写代码片段的位置了,在这里,使用$变量名$来调用我们之前创建的 “变量”。

1
<Code Language="csharp"> <![CDATA[$SystemConsole$.WriteLine($dollars$"$end${}");]]></Code>

在这里我们使用$SystemConsole$来调用<Function>SimpleTypeName(global::System.Console)</Function>这个函数,为我们生成一个当前上下文最短的Console

由于<![CDATA[]]>中,$符号会被解析为变量区域,且无法转义,因此无法直接写入代码片段,通过$dollars$来调用$这个符号,曲线救国,成功将$写入代码片段中。

$end$则表示在代码段生成后,光标所在的位置,设置好光标的位置后,代码片段生成后就能直接继续书写,无需再寻找书写位置。

这样,一个简单的代码片段就算是完成了,如果需要更多选项,请参考官方文档:代码片段及其使用方法

自动导入命名空间

都来写代码片段了,肯定能多方便要多方便了。比如在使用Debug.WriteLine()时,我们在写完后,还需要用Alt+Enter键去导入命名空间,这里我们就简答说一下自动导入命名空间的部分。使用的例子来自于Debug,WriteLine()

在下面的代码中,我们在Snippet下新增了Imports来导入命名空间

1
2
3
4
5
6
7
8
9
10
11
12
<Snippet>
<Declarations>
</Declarations>
<Imports>
<Import>
<Namespace>
System.Diagnostics
</Namespace>
</Import>
</Imports>
<Code Language="csharp"><![CDATA[Debug.WriteLine($end$);]]></Code>
</Snippet>

Imports对单个 Import 元素进行分组。

Import中使用Namespace来 将代码片段使用的命名空间 的导入。

Namespace中写要导入的命名空间

在使用代码片段后, 如果尚不存在命名空间,系统会将 Namespace 元素中指定的命名空间自动添加到代码起始位置处的 using 指令或 Imports 语句中。

自动引入程序集

使用方式其实和自动导入命名空间一样,而且本人并未学习到需要引用程序集的地方,这里就简单整合一个官方的例子

1
2
3
4
5
6
7
8
9
10
11
<Snippet>
<References>
<Reference>
<Assembly> AssemblyName </Assembly>
<Url>... </Url> <!--可选。包含一个提供有关所引用程序集的详细信息的 URL。-->
</Reference>
</References>
<Imports>... </Imports>
<Declarations>... </Declarations>
<Code>... </Code>
</Snippet>

Assembly 元素的文本值可以是程序集的友好文本名称(如 System.dll),也可以是程序集的强名称(如 System,Version=1.0.0.1,Culture=neutral,PublicKeyToken=9b35aa323c18d4fb1)。

Function元素

GenerateSwitchCases 示例

以下示例演示如何使用 GenerateSwitchCases 函数。 插入此代码片段并将枚举输入文本中 $switch_on$ 时,文本 $cases$ 将为枚举中的每个值生成一个 case 语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>switch</Title>
<Shortcut>switch</Shortcut>
<Description>Code snippet for switch statement</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>expression</ID>
<ToolTip>Expression to switch on</ToolTip>
<Default>switch_on</Default>
</Literal>
<Literal Editable="false">
<ID>cases</ID>
<Function>GenerateSwitchCases($expression$)</Function>
<Default>default:</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[
switch ($expression$)
{
$cases$
}
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

ClassName 示例

以下示例演示如何使用 ClassName 函数。 插入此代码片段时, $classname$ 文本将替换为代码文件中该位置的封闭类的名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Common constructor pattern</Title>
<Shortcut>ctor</Shortcut>
<Description>Code Snippet for a constructor</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<Default>int</Default>
</Literal>
<Literal>
<ID>name</ID>
<Default>field</Default>
</Literal>
<Literal default="true" Editable="false">
<ID>classname</ID>
<ToolTip>Class name</ToolTip>
<Function>ClassName()</Function>
<Default>ClassNamePlaceholder</Default>
</Literal>
</Declarations>
<Code Language="csharp" Format="CData">
<![CDATA[
public $classname$ ($type$ $name$)
{
this._$name$ = $name$;
}
private $type$ _$name$;
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

SimpleTypeName 示例

此示例演示如何使用 SimpleTypeName 函数。 将此代码片段插入代码文件中时,文本 $SystemConsole$ 将替换为调用代码片段的上下文中类型的最简单形式 Console 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Console_WriteLine</Title>
<Shortcut>cw</Shortcut>
<Description>Code snippet for Console.WriteLine</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal Editable="false">
<ID>SystemConsole</ID>
<Function>SimpleTypeName(global::System.Console)</Function>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[
$SystemConsole$.WriteLine();
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

个人用简单代码片段

Console.WriteLine($”{}”)

使用cwi生成Console.WriteLine($"{}")字符串插值.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>cwi</Title>
<Shortcut>cwi</Shortcut>
<Description>Console.WriteLine($"{}") 的代码片段</Description>
<Author>RiZhiZhaoYi</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal Editable="false">
<ID>dollars</ID>
<Default>$</Default>
</Literal>
<Literal Editable="false">
<ID>SystemConsole</ID>
<Function>SimpleTypeName(global::System.Console)</Function>
</Literal>
</Declarations>
<Code Language="csharp"> <![CDATA[$SystemConsole$.WriteLine($dollars$"$end${}");]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

Console.ReadLine()

使用 cr生成Console.ReadLine()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>cr</Title>
<Shortcut>cr</Shortcut>
<Description>Console.ReadLine() 的代码片段</Description>
<Author>RiZhiZhaoYi</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal Editable="false">
<ID>SystemConsole</ID>
<Function>SimpleTypeName(global::System.Console)</Function>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[$SystemConsole$.ReadLine();$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

Debug.WriteLine()

使用dw生成Debug.WriteLine();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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>
<Shortcut>dw</Shortcut>
<Description>Debug.WriteLine() 的代码片段</Description>
<Author>RiZhiZhaoYi</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
</Declarations>
<Imports>
<Import>
<Namespace>
System.Diagnostics
</Namespace>
</Import>
</Imports>
<Code Language="csharp"><![CDATA[Debug.WriteLine($end$);]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

普通方法的代码片段

使用method生成一个方法的代码片段,可通过tab键快速切换更改访问修饰符、返回值类型、方法名、参数列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>method</Title>
<Shortcut>method</Shortcut>
<Description>普通方法的代码片段</Description>
<Author>RiZhiZhaoYi</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal Editable="true">
<ID>accessModifier</ID>
<Default>public</Default>
</Literal>
<Literal Editable="true">
<ID>returnType</ID>
<Default>void</Default>
</Literal>
<Literal Editable="true">
<ID>methodName</ID>
<Default>MyMethod</Default>
</Literal>
<Literal Editable="true">
<ID>paramList</ID>
<Default></Default>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[$accessModifier$ $returnType$ $methodName$($paramList$)
{
$end$
}]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
  • 标题: 书写Visual Studio代码片段
  • 作者: 日之朝矣
  • 创建于 : 2024-08-02 22:23:25
  • 更新于 : 2024-08-18 09:25:27
  • 链接: https://blog.rzzy.fun/2024/08/02/visual-studio-code-snippets/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论