[轉]T4系列文章之3:T4語法的介紹

本文轉自:http://www.cnblogs.com/damonlan/archive/2012/03/06/2382724.htmlhtml

由於這段時間一直都沒空,我也不知道有沒有對人T4感興趣,但無論了,先記下在說吧,就當是個人筆記。編程

但願對大家有用。編程語言

若是你對T4還比較陌生,推薦你在複習幾篇文章:ide

One:T4系列文章之1:認識T4工具

Two:T4系列文章之2:T4工具簡介、調試以及T4運行原理 post

複習複習。。學習

T4語言的語法很簡單,能夠說一學就會。它不像C#或者JAVA同樣,那麼多的限制什麼的。因此,只要會C#語言,而後再學習一點T4它應該注意的地方,那麼就OK了。this

是否是很心動了?心動不如行動吧。spa

T4模板的基本結構: 它們基本上能夠分紅5類:指令塊(Directive Block)、文本塊(Text Block)、代碼語句塊(Statement Block)、表達式塊(Expression Block)和類特性塊(Class Feature Block)。debug

你看上面的截圖,把一些基本的都羅列出來了。

一、指令塊(Directive Block)

首先,值須要記住的是 指令塊是已@開頭的。 好比你看到的下面。

和ASP.NET頁面的指令同樣,它們出如今文件頭,經過<#@…#>表示。其中<#@ template …#>指令是必須的,用於定義模板的基本屬性,好比編程語言、基於的文化、是否支持調式等等。比較經常使用的指令還包括用於程序集引用的<#@ assembly…#>,用於導入命名空間的<#@ import…#>等等。

它主要包括如下內容:

1. <#@ import#>

開頭,這個主要表示是說引入命名空間 好比:<#@ import namespace="System.Linq" #>

2. <#@ assembly name="[assembly strong name|assembly file name]" #>

顧名思義 指的是 引入ddl文件,好比<#@ assembly name="System.Core.dll" #>。不過這裏其實沒有必要,由於你只要在當前的引用裏添加dll文件就ok了。 3. <#@ output extension="" #>

 這個是你輸出的格式,好比<#@ output extension=".cs" #>,那麼你輸出的就是.cs文件咯。很好理解。Extension是擴展名的意思嘛。 

5. <#@ template  #>

格式:<#@ template [language="VB"] [hostspecific="true"] [debug="true"] [inherits="templateBaseClass"] [culture="code"] [compilerOptions="options"] #>

 它主要有2個意思:一個只的是寫模板所使用的語言,好比<#@ template  language="C#" #> 那麼我這個模板能夠用C#來些。

另外一個很重要的特性指的是:繼承。就是把一些公共的方法抽象到父模板中,而後能夠在多個模板中進行復用。這個很是有用,我之後會逐步的介紹。 好比:<#@ template language="C#" inherits="CommonTemplate" debug="true" #> CommonTemplate是我寫的一個公共模板。

6. <#@ include file="" #>

這個頗有意思,意思就是說在當前的模板中包含另一個文件中的內容。先來一個很簡單的例子。

  6.1 新建一個空白的文本模板 ,命名爲:MyTextTemplate.tt

  6.2 在新建一個 txt文件,裏面寫入一些字。myText.txt

  6.3 在MyTextTemplate.tt模板中,<#@ include file=」myText.txt」#>

  6.4  而後你就能夠在MyTextTemplate.tt看到 你文本中的一些字符。

    對第六點須要的注意事項:

  1. file的路徑能夠是絕對路徑、相對路徑。

    2.file能夠包括環境變量,但它必須用%包起來。好比<#@ include file="%HOMEPATH%\MyIncludeFile.t4" #>

    3.file後面的文件的擴展名不能包括 .tt結尾的。

若是你須要用.tt的結尾,你須要用4t來代替。這是由於若是你加了.tt後綴的文件名,由於vs會自動是把當前.tt的文件的Custom Tool(自定義工具)屬性設定爲TextTemplatingFileGenerator。

二、文本塊(Text Block)

文本塊就是直接原樣輸出的靜態文本,不須要添加任何的標籤。在上面的模板文件中,處理定義在<#… #>、<#+… #>和<#=… #>中的文本都屬於文本塊。好比在指令塊結束到第一個「<#」標籤之間的內容就是一段靜態的文本塊。

模板內容:

?
<#@ template language= "C#" #>
Hello World!

 

編譯的內容:

?
using System;
using Microsoft.VisualStudio.TextTemplating; 
 
namespace Microsoft.VisualStudio.TextTemplating413AE4BE2CE28AB99
{
     public class GeneratedTextTransformation: TextTransformation
     {
         public override string TransformText()
         {
             this .Write( "Hello World!" );
             return this .GenerationEnvironment.ToString();
         }
     }
}

 

輸出是:Hello World!

三、代碼語句塊(Statement Block)

代碼語句塊經過<#Statement#>的形式表示,中間是一段經過相應編程語言編寫的程序調用,咱們能夠經過代碼語句快控制文本轉化的流程。

其實在咱們的使用中,對語句塊的做用主要就是寫C#代碼。

好比,請看下面:

?
<#
     for ( int i = 0; i < 4; i++)
     {
         Write(i + ", " );
     }
     Write( "4" );
#> Hello!

 那麼輸出的結果就是

0,1,2,3,4

Hello!

凡是能在平時咱們VS裏面書寫的代碼,均可以在<# #>裏表示。

四、表達式塊(Expression Block)

表達式塊以<#=Expression#>的形式表示,經過它之際上動態的解析的字符串表達內嵌到輸出的文本中。

模板內容:

?
<#@ template language= "C#" #>
<#
     for ( int i = 1; i <= 3; i++)
     {
#>
Hello World <#= i #>!
<#
     }
#>

 請注意這個:<#= i #>

後臺編譯的內容:

?
using System;
using Microsoft.VisualStudio.TextTemplating; 
 
namespace Microsoft.VisualStudio.TextTemplating76E036EA7C70CB236
{
    public class GeneratedTextTransformation: TextTransformation
    {
       public override string TransformText()
       {
          for ( int i = 1; i <= 3; i++)
          {
             this .Write( "Hello World " );
             this .Write(ToStringHelper.ToStringWithCulture(i));
             this .Write( "!\r\n" );
          }
          return this .GenerationEnvironment.ToString();
        }
    }
}

  輸出的內容就是:

Hello World 1!
Hello World 2!
Hello World 3!

五、類特性塊(Class Feature Block)

首先咱們須要記住的是 類型性模塊是有個+號的,好比<#+ #>這種類型的。  

若是文本轉化須要一些比較複雜的邏輯,咱們須要寫在一個單獨的輔助方法中,甚至是定義一些單獨的類,咱們就是將它們定義在類特性塊中。類特性塊的表現形式爲<#+ FeatureCode #>,對於Hello World模板,獲得人名列表的InitializePersonList方法就定義在類特性塊中。

其實說白了 就是在裏面寫方法,方便咱們屢次重用和調用,提升咱們的開發效率。

好比:

?
<#@ template language= "C#" #>
<# HelloWorld(); #>
<# HelloWorld(); #>
<#+
     private void HelloWorld()
     {
         this .Write( "Hello World" );
     }
#>

 注意上面的+號的上面有個<# HelloWorld(); #> 。

因此,結果理所固然的就是有2個Hello World。

不過,您須要注意的是,你的這個類特性方法應該放到最後面去,好比你這樣用:

?
<#@ template language= "C#" #>
<# HelloWorld(); #>
<# HelloWorld(); #>
<#+
     private void HelloWorld()
     {
         this .Write( "Hello World" );
     }
#>
<# HelloWorld(); #>

  

很差意思,它會給你報錯,

ErrorGeneratingOutput

由於你不是放到最後面了,因此這裏須要特別特別特別注意一下。

還有就是類特性的功能裏面並 不只僅只是一個方法,它裏面還能夠放不少東西,好比屬性、常量、字段以及其餘能夠在其餘編程裏看到的C#結構均可以插入裏面,咱們足足能夠見到它有多麼強悍的生命力。

好比下面在舉一個例子:

?
<#@ template language= "C#" #>
<# HelloWorld(); #>
<#+
     private string _field = "classy" ;
     private void HelloWorld()
     {
         for ( int i = 1; i <= 3; i++)
         {
#>
Hello <#=_field#> World <#= i #>!
<#+
         }
     }
#>

  

輸出的結果就是:

Hello classy World 1!

Hello classy World 2!

Hello classy World 3!

 

 

OK。T4語言的就簡單的到這裏。寫的比較倉促,但願能獲得諒解。有問題能夠在討論。謝謝。

 

 

 

 

做者:Lanny☆蘭東才         出處:http://www.cnblogs.com/damonlan         Q Q:*********         E_mail:Damon_lan@163.com or Dongcai.lan@hp.com

本博文歡迎你們瀏覽和轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,在『參考』的文章中,我會代表參考的文章來源,尊重他人版權。若您發現我侵犯了您的版權,請及時與我聯繫。

相關文章
相關標籤/搜索