共用方式為


T4 文字範本控制區塊

控制區塊可讓您在文字範本中撰寫程式碼,以變更輸出。 控制區塊有三種,分別以左括號做區分:

  • <# Standard control blocks #> 可包含陳述式。

  • <#= Expression control blocks #> 可包含運算式。

  • <#+ Class feature control blocks #> 可包含方法、欄位和屬性。

標準控制區塊

標準控制區塊包含陳述式。 例如,下列標準區塊會取得 XML 文件中所有屬性的名稱:

<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System.Xml" #>

<#
    List<string> allAttributes = new List<string>();
    XmlDocument xDoc = new XmlDocument();
    xDoc.Load(@"E:\CSharp\Overview.xml");
    XmlAttributeCollection attributes = xDoc.Attributes;
    if (attributes.Count > 0)
    {
       foreach (XmlAttribute attr in attributes)
       {
           allAtributes.Add(attr.Name);
       }
     }  
#>

您可以將純文字嵌入複合陳述式,例如 if 或 for。 例如,下列片段會在每次迴圈反覆運算時產生輸出行:

<#
       foreach (XmlAttribute attr in attributes)
       {
#>
Found another one!
<#
           allAtributes.Add(attr.Name);
       }
#>

警告

永遠使用 {...} 分隔含有內嵌純文字的巢狀陳述式。 下列範例可能無法正確運作:

<# if (ShouldPrint) #> Some text. -- WRONG

而是應該包含 {大括弧},如下所示:

 
<#
 if (ShouldPrint)
 {   //  "{" REQUIRED
#>
Some text.
<#
 } 
#>

運算式控制區塊

運算式控制區塊可在程式碼中用來提供要寫入輸出檔的字串。 例如,沿用上述範例,您可以按照下列內容修改程式碼區塊,將屬性名稱列印到輸出檔:

<#
    XmlDocument xDoc = new XmlDocument();
    xDoc.Load(@"E:\CSharp\Overview.xml");
    XmlAttributeCollection attributes = xDoc.Attributes;
    if (attributes != null)
    {
       foreach (XmlAttribute attr in attributes)
       { 
#>
        <#= attr.Name #>
<#
       }
    }
#>

類別功能控制區塊

您可以使用類別功能控制區塊,將方法、屬性、欄位,甚至巢狀類別加入至文字範本。 類別功能區塊最常見的用途,是在文字範本的其他部分中為程式碼提供 Helper 函式。 例如,下列類別功能區塊會將屬性名稱的第一個字母變成大寫 (或者,如果名稱包含空白字元,則將其中每個字的第一個字母變成大寫):

<#@ import namespace="System.Globalization" #>

<#+
    private string FixAttributeName(string name)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name);
    }
#>
注意事項注意事項

在同一個範本檔中,類別功能控制區塊後面不能接著標準控制區塊。 但這項限制不適用於使用 <#@include#> 指示詞的結果。 每一個被納入的檔案其標準區塊後面可接類別功能區塊。

您可以將文字或運算式區塊嵌入類別功能控制區塊,以建立產生輸出的函式。 例如:

<#+
    private string OutputFixedAttributeName(string name)
    {
#>
 Attribute:  <#= CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name) #>
<#+  // <<< Notice that this is also a class feature block.
    }
#>

您可以從標準區塊或另一個類別功能區塊呼叫這個函式:

<# foreach (Attribute attribute in item.Attributes)
{
  OutputFixedAttributeName(attribute.Name);
}
#>

如何使用控制區塊

單一範本中標準及運算式控制區塊內的所有程式碼 (包括被納入之範本中的所有程式碼) 會合併構成所產生之程式碼的 TransformText() 方法 (如需有關透過 include 指示詞加入其他文字範本的詳細資訊,請參閱T4 文字範本指示詞)。

當您使用控制區塊時,請注意下列考量:

  • **語言。**您可以在文字範本中使用 C# 或 Visual Basic 程式碼。 預設的語言為 C#,但是您可以使用 template 指示詞的 language 參數來指定 Visual Basic (如需 template 指示詞的詳細資訊,請參閱T4 文字範本指示詞)。

    您在控制區塊中使用的語言與在文字範本中所產生之文字的語言或格式無關。 您可以使用 Visual Basic 產生 C#,反之亦然。

    在指定的文字範本 (包括使用 include 指示詞加入的所有文字範本) 中,您只能使用一種語言。

  • 區域變數:由於在範本中標準及運算式控制區塊的所有程式碼都會當做單一方法產生,因此您必須確定不會和區域變數名稱發生衝突。 如果您要加入其他文字範本,必須確定變數名稱在所有被納入的範本之間都是唯一的。 有一個確保符合這項要求的方法就是,在每個區域變數名稱中加入可識別宣告該區域變數之文字範本的字串。

    在宣告區域變數時,特別是在加入多個文字範本時,將區域變數初始化成合理的值,也是不錯的作法。

  • 控制區塊的巢狀結構:控制區塊無法以巢狀方式置於其他區塊內。 您一定要先終止指定的控制區塊,才能再開啟另一個區塊。 例如,下列範例示範如何在運算式區塊中列印一些文字做為標準控制區塊的一部分。

    <# 
    int x = 10;
    while (x-- > 0)
    {
    #>
    <#= x #>
    <# } #>
    
  • 重構:為保持文字範本簡潔易懂,強烈建議您將可重複使用的程式碼分解成類別功能區塊中的 Helper 函式,或是建立繼承 Microsoft.VisualStudio.TextTemplating.TextTransformation 類別的自訂文字範本類別,以避免重複撰寫程式碼。