你能在t4模板中使用全局变量吗?

时间:2014-09-10 19:29:24

标签: t4

如何在TT文件中使用全局变量?

如果我在头文件中声明一个变量,如果我在函数中引用它,我会得到一个编译错误。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<# 
     int ValueForThisFile = 35;

     SomeFunction();
#>

<#+
void SomeFunction() {
#>
    public void GeneratedCode() { 
        int value = <#=ValueForThisFile#>;
    }
<#+
}
#>

我知道我可以将它作为一个参数传递但是有数百个调用,如果我可以避免这种情况,它会在语法上更严格。如果这是一个文件我可以硬编码值,但有几十个文件具有不同的设置和常见的包含生成代码的文件。

3 个答案:

答案 0 :(得分:3)

我认为这是不可能的。当T4解析您的模板时,它实际上正在生成一个类。所有&lt; ##&gt;内容被注入该类的单个方法,而所有&lt;#+#&gt;标签作为该类的方法添加,允许您从单个方法中调用它们&lt; ##&gt;标签。所以&#34; ValueForThisFile&#34;的范围变量仅限于该单一方法。举个简单的例子,这个模板:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<# 
     int ValueForThisFile = 35;

     SomeFunction();
#>

<#+
void SomeFunction() {
   return ValueForThisFile;
}
#>

会生成这样的类:

class T4Gen {

private void MainWork() {
    int ValueForThisFile = 35;
    this.SomeFunction();
}

private void SomeFunction{
    return ValueForThisFile;
}

}

变量&#34; ValueForThisFile&#34;仅限于MainWork功能。实际的T4类生成要复杂得多,但正如你所看到的那样,在这样的代码中没有办法得到全局变量。

答案 1 :(得分:1)

像这样构建你的T4脚本可能有所帮助,我一直在我的项目中成功使用类似的方法: -

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#     
    var Context = new ScriptContext();
    Context.SomeFunction();
#>
// This file is generated by Build/Info.tt, do not modify!
void SomeFunction() {
    public void GeneratedCode() { 
        int value = <#=Context.ValueForThisFile#>;
    }
}

<#+
public class ScriptContext {
    public int ValueForThisFile = 35;

    public void SomeFunction()
    {
        ValueForThisFile = 42;
    }
}
#>

答案 2 :(得分:0)

可以在T4模板中共享各种跨函数,请尝试

<#@ template  debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ import namespace="System.Collections.Generic" #> 
<#
    InitGlobalVariable();
    AddNames();
    ShowNames();

#>

<#+
    //T4 Shared variables
    List<string> names;
#>

<#+

private void InitGlobalVariable()
{
    names = new List<string>();
}

private void AddNames()
{
    names.Add("Mickey");
    names.Add("Arthur");
}

private void ShowNames()
{
    foreach(var name in names)
    {
#>
        <#= name #>
<#+  
    }
}
#>

在<#+ ...#>内声明变量,然后在<#...#>

内初始化