【问题标题】:T4 Text Template - Is it possible to get compilation symbols from host?T4 文本模板 - 是否可以从主机获取编译符号?
【发布时间】:2010-12-31 13:01:25
【问题描述】:

背景:

我有一个用 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
<# { #>

如果有人能说明这是否可能,我将不胜感激!

【问题讨论】:

  • 好奇 - 假设您使用 T4 删除不安全声明属性,您如何处理实际的不安全代码?
  • 显然它不是 only 模板会改变事物的地方 - 其他示例是 Foo* bar 更改为 ref Foo bar,或 bar->foo() 更改为bar.foo()

标签: .net visual-studio-2010 t4


【解决方案1】:

马特, 它们不可用,因为您的项目的编译和模板的编译从 VS2010 开始完全隔离。

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

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

例如一个包含以下内容的简单存根,名为 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 #>

希望这能让你感动。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多