Compartir a través de


Bloques de control de las plantillas de texto

Los bloques de control permiten escribir código en la plantilla de texto para variar el resultado. Hay tres tipos de bloques de control, que se distinguen por sus corchetes de apertura:

  • <# Standard control blocks #> puede contener instrucciones.

  • <#= Expression control blocks #> puede contener expresiones.

  • <#+ Class feature control blocks #> puede contener métodos, campos y propiedades.

Bloque de control estándar

Los bloques de control estándar contienen instrucciones. Por ejemplo, el siguiente bloque estándar obtiene los nombres de todos los atributos del 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);
       }
     }  
#>

Puede incrustar texto sin formato dentro de una instrucción compuesta como if o for. Por ejemplo, este fragmento genera una línea de salida en cada iteración del bucle:

<#
       foreach (XmlAttribute attr in attributes)
       {
#>
Found another one!
<#
           allAtributes.Add(attr.Name);
       }
#>
Nota de precauciónPrecaución

Use siempre {...} para delimitar instrucciones anidadas que contienen texto sin formato incrustado.Puede que el siguiente ejemplo no funcione correctamente:

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

En su lugar, debería incluir {corchetes}, como se muestra a continuación:

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

Bloque de control de expresiones

Los bloques de control de expresiones se utilizan en el código que proporciona cadenas que se van a escribir en el archivo de salida. Por ejemplo, siguiendo el ejemplo anterior, puede imprimir los nombres de los atributos en el archivo de salida modificando el bloque de código de la siguiente manera:

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

Bloque de control de características de clase

Puede utilizar los bloques de control de característica de clase para agregar métodos, propiedades, campos o incluso clases anidadas a la plantilla de texto. El uso más común de los bloques de características de clase es proporcionar funciones auxiliares para el código de otras partes de la plantilla de texto. Por ejemplo, el siguiente bloque de características de clase pone en mayúsculas la primera letra del nombre de atributo (o, si el nombre contiene un espacio en blanco, la primera letra de cada palabra):

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

<#+
    private string FixAttributeName(string name)
    {
        return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(name);
    }
#>
NotaNota

Los bloques de control estándar no deben seguir a un bloque de control de características de clase en el mismo archivo de plantilla.Sin embargo, esta restricción no se aplica al resultado del uso de las directivas <#@include#>.Cada archivo incluido puede tener bloques estándar seguidos por bloques de características de clase.

Puede crear una función que genera resultados mediante la incrustación de bloques de texto y expresión dentro de un bloque de control de características de clase. Por ejemplo:

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

Podría llamar a esta función desde un bloque estándar o desde otro bloque de características de clase:

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

Cómo usar los bloques de control

Todo el código de todos los bloques de control estándar y de expresiones de una única plantilla (incluido el código de las plantillas incluidas) se combina para formar el método TransformText() del código generado. (Para obtener más información sobre cómo incluir otras plantillas de texto con la directiva include, vea Directivas de plantilla de texto T4.)

Debe tener presentes las siguientes consideraciones al utilizar bloques de control:

  • Idioma. Puede utilizar código de C# o de Visual Basic en una plantilla de texto. El lenguaje predeterminado es C#, pero puede especificar Visual Basic con el parámetro language de la directiva template. (Para obtener más información sobre la directiva template, vea Directivas de plantilla de texto T4.)

    El lenguaje que utiliza en los bloques de control no tiene ninguna relación con el lenguaje ni el formato del texto que genera en una plantilla de texto. Puede generar C# utilizando código de Visual Basic o viceversa.

    Solamente puede usar un lenguaje en una plantilla de texto determinada, incluidas todas las plantillas de texto que se agregan con la directiva include.

  • Variables locales. Dado que todo el código de los bloques de control estándar y de expresiones de una plantilla de texto se genera como un método único, debe asegurarse de que no hay ningún conflicto con los nombres de variables locales. Si incluye otras plantillas de texto, debe asegurarse de que los nombres de variable son únicos en todas las plantillas incluidas. Una manera de asegurarse de ello consiste en agregar una cadena a cada nombre de variable local que identifique la plantilla de texto donde se declaró.

    También es buena idea inicializar las variables local en valores razonables al declararlas, en especial cuando incluye varias plantillas de texto.

  • Anidamiento de bloques de control. Los bloques de control no se pueden anidar entre sí. Siempre debe finalizar un bloque de control determinado antes de abrir otro. Por ejemplo, a continuación se muestra cómo imprimir algún texto de un bloque de expresiones como parte de un bloque de control estándar.

    <# 
    int x = 10;
    while (x-- > 0)
    {
    #>
    <#= x #>
    <# } #>
    
  • Refactorización. Para que las plantillas de texto sigan siendo cortas y fáciles de entender, se recomienda evitar el código repetitivo ya sea mediante la factorización del código reutilizable en funciones auxiliares en los bloques de características de clase o bien mediante la creación de una clase de plantilla de texto propia que herede de la clase Microsoft.VisualStudio.TextTemplating.TextTransformation.