在開發的項目的時候,你是否常常遇到須要重複編寫一些相似的代碼,好比是否常常會使用 for、foreach ? 在編寫這兩個循環語句的時候,你是一個字符一個字符敲仍是使用 Visual Studio 提供的Code Snippet 工具自動幫你生成呢?編輯器
你只須要在代碼編輯器中輸入for,就會看到 Visual Studio 的自動提示框中出現了以下紅框框起來的部分,這個時候只須要連按兩下 tab 鍵,便會自動補全 for 循環語句(如圖2所示),而且默認選中索引,以便你進行修改。工具
圖 1 自動提示框post
圖 2 自動補全循環語句ui
是否是很神奇? 與之相似的還有switch、cw (Console.WriteLine)、ctor(構造器)、prop(屬性)等,靈活運用這些就可讓你的 Coding 工做事半功倍,更多默認 CodeSnippet 請查看參考資源[1]。spa
可是,每一個項目都有每一個項目的特殊性,默認的這些 Code Snippet 若是沒法知足您的需求,這個時候就須要自動動手來擴展了。code
在動手開始寫本身的 Code Snippet 以前,得先搞清楚這個玩意兒是怎麼作到的。orm
它其實只是一個 xml,只不過包含了一些只有 Visual Studio 才認識的元素,這些元素就定義瞭如何去替咱們補全代碼(,Code Snippet 針對不一樣的語言如VB、C#、CSS使用不一樣的元素,本文所有按照 C# 語言進行介紹)。xml
下面來看一下 for 的Snippet源代碼是長什麼樣子的對象
1 <?xml version="1.0" encoding="utf-8"?> 2 <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> 3 <CodeSnippet Format="1.0.0"> 4 <Header> 5 <Title>for</Title> 6 <Shortcut>for</Shortcut> 7 <Description>for 循環的代碼段</Description> 8 <Author>Microsoft Corporation</Author> 9 <SnippetTypes> 10 <SnippetType>Expansion</SnippetType> 11 <SnippetType>SurroundsWith</SnippetType> 12 </SnippetTypes> 13 </Header> 14 <Snippet> 15 <Declarations> 16 <Literal> 17 <ID>index</ID> 18 <Default>i</Default> 19 <ToolTip>索引</ToolTip> 20 </Literal> 21 <Literal> 22 <ID>max</ID> 23 <Default>length</Default> 24 <ToolTip>最大長度</ToolTip> 25 </Literal> 26 </Declarations> 27 <Code Language="csharp"><![CDATA[for (int $index$ = 0; $index$ < $max$; $index$++) 28 { 29 $selected$ $end$ 30 }]]> 31 </Code> 32 </Snippet> 33 </CodeSnippet> 34 </CodeSnippets>
一個 CodeSnippet 則主要包含 <Header> 和 <Snippet> 兩部分。上面的結構挺清晰的,一個 <CodeSnippets> 元素能夠包含多個不一樣的 <CodeSnippet> 。blog
其中 <Header> 部分主要是對這個 Snippet 的一個聲明,包括 Snippet 的名稱、描述、做者及 Snippet 的類型(稍後會解釋)。
Header 部分在實際運行中的做用
snippet元素是關鍵的重點,單獨弄一節來具體說明。
完整的 snippet 元素結構以下:
1 <Snippet> 2 <Declarations>... </Declarations> 3 <Code>... </Code> 4 </Snippet>
<Declarations> 元素
該元素用於定義在運行中須要被替換的變量,Microsoft 提供了兩種類型:Literal(文本)和 Object(對象)。MSDN上的解釋以下:
Literal 元素用於標識總體包含在代碼段中、但在插入到代碼中後可能會進行自定義的代碼部分的替換對象。例如,字符串、數字值以及應聲明爲文本的一些變量名。
Object 元素用於標識代碼段所需的、但多是在代碼段外部定義的項。例如,Windows 窗體控件、ASP.NET 控件、對象實例以及類型實例應聲明爲對象。對象聲明須要指定類型。
至於這二者在實際運用中的區別,我還真不清楚。若是哪位大俠對此瞭解,還望指點一二。下面只介紹 Literal 類型。
完整的 <Literal> 結構以下:
1 <Literal Editable="true/false"> 2 <ID>... </ID> 3 <ToolTip>... </ToolTip> 4 <Default>... </Default> 5 <Function>... </Function> 6 </Literal>
ID 用於指定須要被替換的對象名稱,有且只有一個。Editable 意味在生成代碼過程當中能不能直接替換成咱們想要文本,好比 for 循環中的索引變量,默認是 「i」,可是咱們能夠替換成任何本身想要的,好比 「Index」。
Default 表示默認生成代碼時,該對象將被 Default 值給代替。
Function 指示當該對象在獲取焦點的時候將要執行的方法。在 Visual Studio 中目前只支持三個方法:GenerateSwitchCases(EnumerationLiteral)、ClassName()、SimpleTypeName(TypeName)。
其中 GenerateSwitchCases 顧名思義是用於爲switch的變量生成case條件的。
ClassName方法用於獲取當前的類名。
SimpleTypeName 則用於縮短類型的名字,由於有些時候有些程序集不會被using進來,這個時候對該程序集中某一類型的調用就須要使用 「名稱空間.類型名稱」 這種方式。可是若是當前的文件已經把須要的程序集using進來了,那這種調用方式就顯得是畫蛇添足。經過使用 SimpleTypeName 就能在生成代碼的時候幫助咱們判斷是否須要加上名稱空間這個前綴。
<Code> 元素
這纔是咱們的主角,由於咱們的代碼就是寫在了該元素內部。先來看一個例子:
1 <Code Language="csharp"><![CDATA[for (int $index$ = 0; $index$ < $max$; $index$++) 2 { 3 $selected$ $end$ 4 }]]>
上面的代碼至關簡單,全部須要在生成代碼的時候被替換的內容都用 $ 包裹,如$index$,記住這個被包裹的內容必須在 <Declarations> 被正肯定義過。由於代碼中可能會有一些在XML中有特殊含義的字符,因此用CDATA進行包裹,防止錯誤轉義。
$selected$ 和 $end$ 是保留的關鍵字,其中 $end$ 用於指示當代碼插入完畢後,光標應該位於的位置。$selected$ 用於表示在生成代碼前你所選中的文本,並在生成代碼的過程當中使用你選中的文本替換 $selected$,經常使用於 SurroundWith 這種類型的 Code Snippet 中。
根據咱們的使用方式,snippet 分爲 Expansion、SurroundsWith 及 Refactoring(只能在重構過程當中使用,自定義的 Code Snippet 不能使用)。
Expansion:容許將代碼段插入到光標處。
SurroundsWith:容許將此代碼段放置在一段選定的代碼周圍。好比咱們寫完一段代碼後,發現忘記加 try...catch... 了,這個時候能夠選中須要包裹在 try...catch... 中的代碼,而後調用 Code Snippet。
若是對上面的結構有了基本瞭解,下面就來實踐一下吧。經過本節,咱們要實現自動生成 Debug.WriteLine 的 snippet。
首先,打開 Visual Stuido / 文件 / 新建 / 文件,選擇 xml 類型。
在 xml 文件中,輸入最小的snippet代碼。
1 <?xml version="1.0" encoding="utf-8"?> 2 <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> 3 <CodeSnippet Format="1.0.0"> 4 <Header> 5 <Title></Title> 6 </Header> 7 <Snippet> 8 <Code Language=""> 9 <![CDATA[]]> 10 </Code> 11 </Snippet> 12 </CodeSnippet> 13 </CodeSnippets>
修改如上的代碼,包括 Header 部分和 Snippet 部分,別忘記指定Language。
1 <?xml version="1.0" encoding="utf-8"?> 2 <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> 3 <CodeSnippet Format="1.0.0"> 4 <Header> 5 <Title>dw</Title> 6 <Description>Debug.WriteLine</Description> 7 <Shortcut>dw</Shortcut> 8 <Author>Charley</Author> 9 </Header> 10 <Snippet> 11 <Declarations> 12 <Literal> 13 <ID>text</ID> 14 <ToolTip>但願輸出的內容</ToolTip> 15 <Default>"text"</Default> 16 </Literal> 17 </Declarations> 18 <Code Language="csharp"> 19 <![CDATA[Debug.WriteLine($text$);$end$]]> 20 </Code> 21 </Snippet> 22 </CodeSnippet> 23 </CodeSnippets>
若是嫌本身寫太麻煩,也可使用開源的 snippet 編輯工具,詳見參考資源[2]。
新建完一個snippet以後,該如何才能在項目中用起來呢?
工具 / 代碼段管理器 打開管理器。
使用 「導入」 將自定義的文件導入進來。
爲本身的 snippet 選擇一個位置。
點擊完成就已經成功了。在代碼編輯器中,輸入 dw 就會發現 Visual Stuido 的智能提示已經出現了咱們的 snippet。
相比於 Expansion 類型的 snippet,使用 SurroundsWith 相對要麻煩點。
本人認爲最快捷的方式就是使用鍵盤快捷鍵,在代碼編輯器中 CTRL+K, CTRL+S,就能夠呼出 snippet。
而後用鍵盤或鼠標選擇目標 snippet。
[2] Snippet Editor