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

发布于 2024-10-09 22:59:54 字数 620 浏览 3 评论 0原文

背景

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

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

Background:

I have an open source game library written in C# which is highly tuned for performance, using unsafe code, pointer arithmetic etc. I've recently ported the library to Windows Phone. Unfortunately Windows Phone does not support unsafe code at all, so I have had to litter my source code with preprocessor directives such as this:

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

Due to the amount of these directives the codebase has become quite unreadable and difficult to maintain, so I've been exploring other options - one of which is text templates using T4.

The Question:

What I need to know before going too far down the T4 route is wether or not it is possible to get compilation symbols from within a text template? I have looked into template parameters but it didn't seem very easy to modify them from the outside world. Ideally what I'd like to see is something a bit like this:

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

If anyone could shed some light on wether or not this is possible I'd be grateful!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我最亲爱的 2024-10-16 22:59:54

马特,
它们不可用,不可用,因为从 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 #>

希望这能让你感动。

Matt,
They're not available, no as the compilation for your project and the compilation for the templates are completely isolated as of VS2010.

However I have a (somewhat clumsy) workaround for you.

If you include a stub file that contains your template directive, then you can set compiler options with the appropriate symbol for compilation.

e.g. a simple stub containing the following, named Define.t4:

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

Put this in a subdirectory named XBOX and put a similar one in a directory named PHONE

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

Note the compiler symbol definitions.

Now set an environment variable to be either XBOX or PHONE - let's say ARCHITECTURE

Now instead of the template directive in your templates, include the Define.t4 file and you will be able to use regular C#/VB condition syntax. Don't forget to put the #if on their own line. Here's an example:

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

Hope this gets you moving.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文