背景
我有一个用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
<# { #>
如果有人能够对某些事情有所了解,那么这是可能的,我将不胜感激!
答案 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 #>
希望这会让你感动。