Поделиться через


Управляющие блоки текстовых шаблонов

Управляющие блоки позволяют создавать код в текстовом шаблоне для изменения вывода.Существует три вида управляющих блоков, которые отличаются друг от друга открывающими скобками:

  • <# 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 #>
<#
       }
    }
#>

Управляющий блок элементов класса

Управляющие блоки элементов класса можно использовать для добавления в шаблон методов, свойств полей и даже вложенных классов.Наиболее распространенным применением блоков элементов класса является предоставление вспомогательных функций для кода в других частях текстового шаблона.Например, следующий блок элементов класса переводит первую букву имени атрибута в верхний регистр (или, если это имя содержит пробелы, переводит в верхний регистр первую букву каждого слова).

<#@ 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.)

При использовании управляющих блоков помните о следующем.

  • Язык. () Язык. В текстовом шаблоне можно использовать язык Visual C# или Visual Basic.По умолчанию используется язык C#, а для использования языка Visual Basic нужно указать его в параметре language директивы template.(Дополнительные сведения о директиве template см. в разделе Директивы текстовых шаблонов T4.)

    Язык, используемый в управляющих блоках, никак не связан с языком или форматом текста, генерируемого в текстовом шаблоне.Можно генерировать код на языке Visual C#, используя код на языке Visual Basic, и наоборот.

    В пределах конкретного текстового шаблона, включая и те шаблоны, которые в него интегрируются с помощью директивы include, можно использовать только один язык.

  • Локальные переменные. () Локальные переменные. поскольку весь код в стандартных управляющих блоках и управляющих блоках выражений в текстовом шаблоне генерируется как один метод, необходимо убедиться в отсутствии конфликтов с именами локальных переменных.Если вы используете другие текстовые шаблоны, убедитесь, что имена переменных уникальны во всех включаемых шаблонах.Один из способов обеспечения такой уникальности заключается в добавлении к имени каждой локальной переменной строки, идентифицирующей текстовый шаблон, в котором она объявлена.

    Также хорошей практикой является инициализация локальных переменных подходящими значениями при их объявлении, особенно при включении нескольких текстовых шаблонов.

  • Вложение управляющих блоков. () Вложенность управляющих блоков. Управляющие блоки не могут вставляться один в другой.Необходимо всегда закрывать управляющий блок перед открытием следующего.Например, ниже показано, как вывести некоторый текст в блоке выражения как часть стандартного управляющего блока.

    <# 
    int x = 10;
    while (x-- > 0)
    {
    #>
    <#= x #>
    <# } #>
    
  • Рефакторинг. () Рефакторинг.Для того чтобы текстовые шаблоны были короткими и понятными, рекомендуется избегать повторяющегося кода путем переноса многократно используемого кода во вспомогательные функции в блоках элементов класса или путем создания собственного класса текстового шаблона, наследующего класс Microsoft.VisualStudio.TextTemplating.TextTransformation.