T4 (مجموعة أدوات تحويل قالب النص) لإنشاء مجموعة من الأنواع بناءً على قائمة الأنواع الأساسية EG Pointi32 ، pointf32 إلخ. في C#
-
20-09-2019 - |
سؤال
مشابه ل 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 وما إلى ذلك ، لكن هذا ليس هو النقطة هنا. هذا هو المقصود كمثال بسيط لتوليد التعليمات البرمجية لأنواع أساسية متعددة.
يتم الترحيب بتعليقات لتحسين هذا أو ما شابه.