在使用 Visual Studio 作为我们的IDE进行开发时,使用如cw
等快速生成代码片段Console.WriteLine()
能显著的提升我们的编码速度。但随着日常的学习,已有的代码片段已经无法满足我们的需求了,因此这里就来介绍如何简单的创建一个自定义代码片段。
由于本人技术与研究时间问题,且并未通过官方文档找到关于如何获取已编写代码的内容,这里并不能写出复杂的代码片段,如通过ctor
生成带有所有成员变量的构造函数。
文章末尾会放几个本人常用的代码片段,需要的可以通过标题查看是否有需要的,直接跳转复制粘贴。
官方文档:代码片段及其使用方法
代码片段
首先我们可以在 Visual Studio 中的 菜单栏 -> 工具 -> 代码片段管理器
中,通过筛选编程语言,来找到现有的代码片段。
如我们可以在Visual C#
中找到经常使用的class
,ctor
、cw
等。
同时在上面我们可以看到这个代码片段的所在位置,我们后续就通过这些默认的代码片段来书写我们自己的代码片段。
写属于自己的代码片段
这里通过一个简单的例子,来过一下写代码片段的流程,我们的目标是使用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> <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> </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>
|