T4文本模板 - 是否可以从主机获取编译符号?

时间:2010-12-28 19:23:58

标签: .net visual-studio-2010 t4

背景

我有一个用C#编写的开源游戏库,它使用不安全的代码,指针算法等高度优化性能。我最近将该库移植到了Windows Phone。不幸的是,Windows Phone根本不支持不安全的代码,因此我不得不使用预处理程序指令来丢弃我的源代码,例如:

#if WINDOWS || XBOX
public unsafe struct Foo
#elif WINDOWS_PHONE
public struct Foo
#endif

由于这些指令的数量,代码库变得非常难以理解且难以维护,所以我一直在探索其他选项 - 其中一个是使用T4的文本模板。

问题:

在走向T4路线太远之前我需要知道的是,是否可以从文本模板中获取编译符号?我已经查看了模板参数,但从外部世界修改它们似乎并不容易。理想情况下,我希望看到的东西有点像这样:

<# if (Host.CompilationSymbols.Contains("WINDOWS_PHONE") { #>
public struct Foo
<# { #>

如果有人能够对某些事情有所了解,那么这是可能的,我将不胜感激!

1 个答案:

答案 0 :(得分:5)

马特 它们不可用,没有作为项目的编译,从VS2010开始,模板的编译完全被隔离。

但是我有一个(有些笨拙)的解决方法。

如果包含包含模板指令的存根文件,则可以使用适当的符号设置编译器选项以进行编译。

e.g。包含以下内容的简单存根,名为Define.t4:

<#@ template compilerOptions="/d:XBOX" debug="false" hostspecific="false" language="C#" #>

将其放在名为XBOX的子目录中,并将类似的目录放在名为PHONE

的目录中
<#@ template compilerOptions="/d:PHONE" debug="false" hostspecific="false" language="C#" #>

请注意编译器符号定义。

现在将环境变量设置为XBOX或PHONE - 假设为ARCHITECTURE

现在代替模板中的模板指令,包含Define.t4文件,您将能够使用常规的C#/ VB条件语法。别忘了将#if放在自己的行上。这是一个例子:

<#@ include file="$(ProjectDir)%ARCHITECTURE%\Define.t4" #>
<#@ output extension=".txt" #>
<#
#if XBOX #>
public unsafe struct Foo
<#
#else #>
public struct Foo
<#
#endif #>

希望这会让你感动。