2010-02-02 131 views
0

我有一个名为IterateThroughChildren()的函数,我想编写代码以从该函数内部发出代码。递归块T4模板

通常情况下,代码块包含在<##中,并且自定义函数包含在<#+#>中,我们在<#=#>块中发送我们的代码。我想发出的代码,如果我想递归执行上述功能是什么,并根据一些逻辑即

<# 
    //Code to get child and parent data 
    IterateThroughChildren(object child, object parent); 
#> 

<#+ 
void IterateThroughChildren(object c, object p) 
{ 
if(c is abc) 
{ 
    if(p is def) 
    { 
    //emit some code here i.e WriteLine(SomeThing); ????? 
    foreach (var item in def.Item) 
    { 
    IterateThroughChildren(item, def); 
    } 

    } 
} 

. 
. 
. 

//and so on 

} 

#> 

回答

2

当您使用T4类的功能块,即<#+ #>,那么代码将成为生成模板输出文件的基础类的一部分。在Visual Studio 2008中,该基础类派生自抽象类Microsoft.VisualStudio.TextTemplating.TextTransformation

因此,可以通过使用继承写()的WriteLine()方法直接写入到输出流。例如,在你的代码:

<# 
    //Code to get child and parent data 
    IterateThroughChildren(object child, object parent); 
    #> 

    <#+ 
    void IterateThroughChildren(object c, object p) 
    { 
    if(c is abc) 
    { 
    if(p is def) 
    { 
    //emit some code here i.e WriteLine(SomeThing); ????? 
    this.WriteLine(SomeThing); // writes SomeThing to the output file 
    foreach (var item in def.Item) 
    { 
    IterateThroughChildren(item, def); 
    } 

    } 
    } 

. . . 

//and so on 

} 

#> 

其中this.WriteLine(东西)是我说的唯一的事。

2

我知道这是一个老问题,但还是想和大家分享:你可以通过使用完全避免使用Write()WriteLine()方法的Action<>

<# 
    Action<object,object> IterateThroughChildren = null; // null to avoid compile-time error 
    IterateThroughChildren = delegate(object c, object p) 
    { 
     if(c is abc) 
     { 
      if(p is def) 
      { 
#> 
// Emit some code here. No WriteLine() or Write() needed! 
<# 
      } 

      foreach (var item in def.Item) 
      { 
       IterateThroughChildren(item, def); 
      } 
     } 
    } 

    //Code to get child and parent data 
    IterateThroughChildren(child, parent); 
#> 

的积累和委托的拆除造成有些丑陋的代码,但在中间使用<#...#>语法有很多优点。

(我知道该示例是错误的代码,但我试图尽可能反映接受的答案的伪代码。)