Compartilhar via


T4 Blocos de controle de modelo de texto

Blocos de controle permitem que você escreva código em seu modelo de texto para variar a saída. Existem três tipos de blocos de controle, que são diferenciados por seus colchetes de abertura:

  • <# Standard control blocks #>pode conter instruções.

  • <#= Expression control blocks #>pode conter expressões.

  • <#+ Class feature control blocks #>pode conter propriedades, métodos e campos.

Bloco de controle padrão

Blocos de controle padrão contêm instruções. Por exemplo, o seguinte bloco padrão obtém os nomes de todos os atributos do documento 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);
       }
     }  
#>

Você pode incorporar texto sem formatação dentro de uma declaração composta como if ou for. Por exemplo, esse fragmento gera uma linha de saída em cada iteração do loop:

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

Aviso

Sempre use {...} para delimitar instruções aninhadas que contenham o texto sem formatação de incorporado. O exemplo a seguir pode não funcionar corretamente:

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

Em vez disso, você deve incluir as chaves {}, da seguinte maneira:

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

Bloco de controle de expressão

Blocos de controle de expressão são usados para o código que fornece as seqüências de caracteres a serem gravados para o arquivo de saída. Por exemplo, com o exemplo acima, você pode imprimir os nomes dos atributos de arquivo de saída, modificando o bloco de código da seguinte maneira:

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

Bloco de controle de recurso de classe

Você pode usar blocos de controle de recurso de classe para adicionar métodos, propriedades, campos ou classes aninhadas, mesmo para o modelo de texto. O uso mais comum de blocos de recurso de classe é fornecer funções auxiliares para código em outras partes do modelo de texto. Por exemplo, o seguinte bloco de recurso de classe coloca em maiúscula a primeira letra do nome do atributo (ou, se o nome contém espaços em branco, ele coloca em maiúscula a primeira letra de cada palavra):

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

<#+
    private string FixAttributeName(string name)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name);
    }
#>
ObservaçãoObservação

Um bloco de controle de recurso de classe não deve ser seguido pelos blocos de controle padrão no mesmo arquivo de modelo. No entanto, essa restrição não se aplica ao resultado do uso de <#@include#> diretivas. Cada arquivo incluído pode ter seguidos de blocos de recurso de classe de blocos padrão.

Você pode criar uma função que gera a saída, incorporando os blocos de texto e a expressão dentro de um bloco de controle de recurso de classe. Por exemplo:

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

Você poderia chamar essa função a partir de um bloco padrão ou outro bloco de recurso de classe:

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

Como usar os blocos de controle

Todo o código em todos os blocos de controle padrão e a expressão em um modelo único (incluindo a todo o código em modelos incluídos) é combinado ao formulário de TransformText() o método do código gerado. (Para obter mais informações sobre como incluir outros modelos de texto com o include diretiva, consulte T4 Diretivas de modelo de texto.)

Você deve ter em mente as seguintes considerações ao usar blocos de controle:

  • Idioma. Você pode usar C# ou Visual Basic de código em um modelo de texto. O idioma padrão é C#, mas você pode especificar o Visual Basic com o language parâmetro do template diretiva. (Para obter mais informações sobre o template diretiva, consulte T4 Diretivas de modelo de texto.)

    O idioma usado em blocos de controle não tem nada a ver com o idioma ou formato do texto que você gerar um modelo de texto. Você pode gerar C# usando o Visual Basic de código- e vice-versa.

    Você pode usar apenas um idioma em um modelo de texto fornecido, incluindo os modelos de texto incluídos com o include diretiva.

  • Variáveis locais. Desde que os blocos de todo o código no controle padrão e a expressão em um modelo de texto será gerado como um único método, você deve se certificar de que não há nenhum conflito com os nomes de variáveis locais. Se você estiver incluindo outros modelos de texto, você deve Certifique-se de que os nomes de variáveis são exclusivos para modelos todos incluídos. Uma maneira de garantir isso é adicionar uma seqüência de caracteres para cada nome de variável local que identifica o modelo de texto na qual ela foi declarada.

    Também é uma boa idéia para inicializar as variáveis de locais para valores razoáveis, ao declará-los, especialmente quando você estiver incluindo vários modelos de texto.

  • Aninhamento de blocos de controle. Blocos de controle não podem ser aninhados dentro de si. Você sempre deve encerrar um bloco de controle fornecido antes de abrir outro. Por exemplo, a seguir mostra como imprimir um texto em um bloco de expressão, como parte de um bloco de controle padrão.

    <# 
    int x = 10;
    while (x-- > 0)
    {
    #>
    <#= x #>
    <# } #>
    
  • Refatoração. Para manter seus modelos de texto curtos e fácil de entender, é altamente recomendável que você evite código repetitivo, levando-se o código reutilizável em funções do auxiliar em blocos de recurso de classe ou criando sua própria classe de modelo de texto que herda da classe TextTransformation.