T4 (boîte à outils de transformation du modèle de texte) pour générer un ensemble de types basé sur une liste de types de base, par exemple POINTI32, POINTF32 etc. en C #

StackOverflow https://stackoverflow.com/questions/2252629

Question

Semblable à Boostez la bibliothèque du préprocesseur pour générer un ensemble de types basé sur une liste de types de base, par exemple POINI32, POINTF32 etc. en C ++ / CLI Je demande comment générer:

struct Point##TYPE_SUFFIX_NAME
{
    TYPE X
    { get; set; }
    TYPE Y;
    { get; set; }

    // Other code
};

Pour différents types de données de base (pod), par exemple:

PointF32, PointF64, PointI32 etc.

Utilisation de T4 (Text Template Transformation Toolkit) dans Visual Studio 2008 ou version ultérieure.

Voir http://www.olegsych.com/2007/12/text-template-transformation-toolkit/ et http://msdn.microsoft.com/en-us/library/bb126445.aspx

Était-ce utile?

La solution

Eh bien, j'ai la réponse moi-même. J'ai créé les fichiers T4 Inclut suivants:

  • SignedIntegersSuffices.ttinclude
  • UnsignedIntegersSuffices.ttinclude
  • IntegersSuffices.ttinclude
  • FloatsSuffices.ttinclude
  • BasicTypesSuffices.ttinclude

Et puis le modèle T4 réel est PointTypes.tt. Ces fichiers sont simplement ajoutés à un projet C # et Visual Studio détectera le .tt et générer une correspondance PointTypes.cs Fichier, chaque fois que le fichier .TT est enregistré.

Ces fichiers sont répertoriés dans ce qui suit.

SignedIntegersSuffices.ttinclude

<#+
IEnumerable<KeyValuePair<string, string>> SignedIntegersSuffices()
{
    var signedIntegersSuffices = new KeyValuePair<string, string>[] { 
        new KeyValuePair<string, string>("sbyte", "I8"),
        new KeyValuePair<string, string>("short", "I16"),
        new KeyValuePair<string, string>("int", "I32"),
        new KeyValuePair<string, string>("long", "I64")
    };
    return signedIntegersSuffices;
}
#>

UnsignedIntegersSuffices.ttinclude

<#+
IEnumerable<KeyValuePair<string, string>> UnsignedIntegersSuffices()
{
    var signedIntegersSuffices = new KeyValuePair<string, string>[] { 
        new KeyValuePair<string, string>("byte", "UI8"),
        new KeyValuePair<string, string>("ushort", "UI16"),
        new KeyValuePair<string, string>("uint", "UI32"),
        new KeyValuePair<string, string>("ulong", "UI64")
    };
    return signedIntegersSuffices;
}
#>

IntegersSuffices.ttinclude

<#@ include file="SignedIntegersSuffices.ttinclude" #>
<#@ include file="UnsignedIntegersSuffices.ttinclude" #>
<#+
    // Insert any template procedures here
    IEnumerable<KeyValuePair<string, string>> IntegersSuffices()
    {
        var integersSuffices = SignedIntegersSuffices().Concat(UnsignedIntegersSuffices());
        return integersSuffices;
    }
#>

FloatsSuffices.ttinclude

<#+
    // Insert any template procedures here
    IEnumerable<KeyValuePair<string, string>> FloatsSuffices()
    {
        var floatsSuffices = new KeyValuePair<string, string>[] { 
            new KeyValuePair<string, string>("float", "F32"),
            new KeyValuePair<string, string>("double", "F64")
        };
        return floatsSuffices;
    }
#>

BasicTypesSuffices.ttinclude

<#@ include file="IntegersSuffices.ttinclude" #>
<#@ include file="FloatsSuffices.ttinclude" #>
<#+
    // Insert any template procedures here
    IEnumerable<KeyValuePair<string, string>> BasicTypesSuffices()
    {
        var basicTypesSuffices = IntegersSuffices().Concat(FloatsSuffices());
        return basicTypesSuffices;
    }
#>

Et enfin le fichier de modèle réel PointTypes.tt:

<#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" language="C#v3.5" debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="System.dll" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ include file="BasicTypesSuffices.ttinclude" #>
namespace TextTemplatesTest
{
<#
    const string pointPrefix = "Point";
    foreach (var typeSuffix in BasicTypesSuffices())
    {
        string type = typeSuffix.Key;
        string suffix = typeSuffix.Value;
#>
    public struct <#= pointPrefix #><#= suffix #>
    {
        <#= pointPrefix #><#= suffix #>(<#= type #> x, <#= type #> y)
            : this()
        {
            X = x;
            Y = y;
        }

        public <#= type #> X
        { get; set; }
        public <#= type #> Y
        { get; set; }
    }
<#
    }
#>
}

Le fichier de sortie PointTypes.cs ressemblera alors à ceci:

namespace TextTemplatesTest
{
    public struct PointI8
    {
        PointI8(sbyte x, sbyte y)
            : this()
        {
            X = x;
            Y = y;
        }

        public sbyte X
        { get; set; }
        public sbyte Y
        { get; set; }
    }
    public struct PointI16
    {
        PointI16(short x, short y)
            : this()
        {
            X = x;
            Y = y;
        }

        public short X
        { get; set; }
        public short Y
        { get; set; }
    }
    public struct PointI32
    {
        PointI32(int x, int y)
            : this()
        {
            X = x;
            Y = y;
        }

        public int X
        { get; set; }
        public int Y
        { get; set; }
    }
    public struct PointI64
    {
        PointI64(long x, long y)
            : this()
        {
            X = x;
            Y = y;
        }

        public long X
        { get; set; }
        public long Y
        { get; set; }
    }
    public struct PointUI8
    {
        PointUI8(byte x, byte y)
            : this()
        {
            X = x;
            Y = y;
        }

        public byte X
        { get; set; }
        public byte Y
        { get; set; }
    }
    public struct PointUI16
    {
        PointUI16(ushort x, ushort y)
            : this()
        {
            X = x;
            Y = y;
        }

        public ushort X
        { get; set; }
        public ushort Y
        { get; set; }
    }
    public struct PointUI32
    {
        PointUI32(uint x, uint y)
            : this()
        {
            X = x;
            Y = y;
        }

        public uint X
        { get; set; }
        public uint Y
        { get; set; }
    }
    public struct PointUI64
    {
        PointUI64(ulong x, ulong y)
            : this()
        {
            X = x;
            Y = y;
        }

        public ulong X
        { get; set; }
        public ulong Y
        { get; set; }
    }
    public struct PointF32
    {
        PointF32(float x, float y)
            : this()
        {
            X = x;
            Y = y;
        }

        public float X
        { get; set; }
        public float Y
        { get; set; }
    }
    public struct PointF64
    {
        PointF64(double x, double y)
            : this()
        {
            X = x;
            Y = y;
        }

        public double X
        { get; set; }
        public double Y
        { get; set; }
    }
}

Assez simple et assez efficace. Maintenant, bien sûr, cela aurait pu être fait en utilisant des génériques, etc., mais ce n'est pas le point ici. Cela est censé être un exemple simple de génération de code pour plusieurs types de base.

Les commentaires pour améliorer cela ou similaires sont les bienvenus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top