Текстовый шаблон T4 - возможно ли получить символы компиляции с хоста? - PullRequest
6 голосов
/ 28 декабря 2010

Справочная информация:

У меня есть библиотека игр с открытым исходным кодом, написанная на C #, которая настроена на производительность, использует небезопасный код, арифметику указателей и т. Д. Я недавно портировал библиотеку на Windows Phone. К сожалению, Windows Phone вообще не поддерживает небезопасный код, поэтому мне пришлось засорять мой исходный код директивами препроцессора, такими как эта:

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

Из-за количества этих директив кодовая база стала совершенно нечитаемой и сложной для обслуживания, поэтому я изучал другие варианты, одним из которых являются текстовые шаблоны, использующие T4.

Вопрос:

Что мне нужно знать, прежде чем идти слишком далеко по маршруту Т4, является ли он более влажным, или нет возможности получить символы компиляции из текстового шаблона? Я изучил параметры шаблона, но изменить их из внешнего мира было не так просто. В идеале я бы хотел увидеть что-то вроде этого:

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

Если бы кто-нибудь мог пролить свет на погоду или нет, это возможно, я был бы благодарен!

1 Ответ

5 голосов
/ 31 декабря 2010

Мэтт, Они недоступны, нет, так как компиляция для вашего проекта и компиляция для шаблонов полностью изолированы от 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 #>

Надеюсь, это заставит вас двигаться.

...