struct Point##TYPE_SUFFIX_NAME
{
TYPE X
{ get; set; }
TYPE Y;
{ get; set; }
// Other code
};
用于不同的基本(POD)数据类型,例如:
PointF32, PointF64, PointI32 etc.
在Visual Studio 2008或更高版本中使用T4(文本模板转换工具包)。
请参阅http://www.olegsych.com/2007/12/text-template-transformation-toolkit/和http://msdn.microsoft.com/en-us/library/bb126445.aspx
答案 0 :(得分:2)
好吧,我有自己的答案。我创建了以下T4包含文件:
SignedIntegersSuffices.ttinclude
UnsignedIntegersSuffices.ttinclude
IntegersSuffices.ttinclude
FloatsSuffices.ttinclude
BasicTypesSuffices.ttinclude
然后实际的T4模板为PointTypes.tt
。这些文件只是添加到C#项目中,只要保存.tt文件,Visual Studio就会检测.tt
并生成匹配的PointTypes.cs
文件。
以下列出了这些文件。
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; }
}
}
非常简单而且非常有效。当然,现在可以使用泛型等来完成,但这不是重点。这是一个用于多种基本类型的代码生成的简单示例。
欢迎提出改进或类似的评论。