T4 (مجموعة أدوات تحويل قالب النص) لإنشاء مجموعة من الأنواع بناءً على قائمة الأنواع الأساسية EG Pointi32 ، pointf32 إلخ. في C#

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

سؤال

مشابه ل Boost Preprocessor Library لإنشاء مجموعة من الأنواع بناءً على قائمة الأنواع الأساسية EG Pointi32 ، PointF32 وما إلى ذلك في C ++/CLI أنا أسأل عن كيفية توليد:

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

    // Other code
};

لمختلف أنواع البيانات الأساسية (POD) على سبيل المثال:

PointF32, PointF64, PointI32 etc.

باستخدام T4 (مجموعة أدوات تحويل قالب النص) في Visual Studio 2008 أو أحدث.

نرى http://www.olegsych.com/2007/12/text-template-transformation-toolkit/ و http://msdn.microsoft.com/en-us/library/bb126445.aspx

هل كانت مفيدة؟

المحلول

حسنًا ، لديّ الإجابة بنفسي. لقد قمت بإنشاء ملفات T4 التالية:

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

ثم قالب T4 الفعلي PointTypes.tt. تتم إضافة هذه الملفات ببساطة إلى مشروع C# وستكتشف Visual Studio .tt وتوليد مطابقة PointTypes.cs ملف ، كلما تم حفظ ملف .tt.

يتم سرد هذه الملفات في ما يلي.

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

وأخيرا ملف القالب الفعلي 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; }
    }
<#
    }
#>
}

ملف الإخراج PointTypes.cs سيبدو هكذا:

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; }
    }
}

بسيطة جدا وفعالة جدا. الآن ، بالطبع ، كان من الممكن القيام بذلك باستخدام Generics وما إلى ذلك ، لكن هذا ليس هو النقطة هنا. هذا هو المقصود كمثال بسيط لتوليد التعليمات البرمجية لأنواع أساسية متعددة.

يتم الترحيب بتعليقات لتحسين هذا أو ما شابه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top