Gavin Stevens's Blog

the ramblings of another developer....

  Home  |   Contact  |   Syndication    |   Login
  34 Posts | 0 Stories | 57 Comments | 212 Trackbacks

News

Archives

Post Categories

I've been doing some work with T4 templates lately and ran into an issue which I couldn't find an answer to anywhere.  I finally figured it out, so I thought I'd share the solution.

I was trying to generate a code class with a T4 template which used generics

The end result a method like:

public IEnumerator GetEnumerator()
            {
                return new TableEnumerator<Table>(_page);
            }

the related section of the T4 template looks like this:

 public IEnumerator GetEnumerator()
            {
                return new TableEnumerator<#=renderClass.Name#>(_page);
            }

But this of course is missing the Generic Syntax for < > which T4 complains about because < > are reserved.

using syntax like <#<#><#=renderClass.Name#><#=<#> won't work becasue the TextTransformation engine chokes on them.  resulting in : Error 2 The number of opening brackets ('<#') does not match the number of closing brackets ('#>') 

even trying to escape the characters won't work: <#\<#><#=renderClass.Name#><#\<#> this results in:

Error 4 A Statement cannot appear after the first class feature in the template. Only boilerplate, expressions and other class features are allowed after the first class feature block. 

The final solution delcares a few strings to represent the literals like this:

<#+
   void RenderCollectionEnumerator(RenderCollection renderClass)
 {  
  string open = "<";
  string close =">";
#>
   public partial class <#=renderClass.Name#> : IEnumerable
        {
            private readonly PageBase _page;
            public <#=renderClass.Name#>(PageBase page)
            {
                _page = page;
            }

            public IEnumerator GetEnumerator()
            {
                return new TableEnumerator<#=open#><#=renderClass.Name#><#=close#>(_page);
            }
        }
<#+
 } 
#>

This works, and everyone is happy, resulting in an automatically generated class enumerator, complete with generics!

Hopefully this will save someone some time :)

posted on Saturday, March 13, 2010 4:13 PM

Feedback

# re: Escaping Generics with T4 Templates 9/26/2010 8:56 PM PATRICK XIONG
Thanks for sharing. I ran into a similar issue. After read your post I found you also can change
return new TableEnumerator<#=open#><#=renderClass.Name#><#=close#>(_page);

to

return new TableEnumerator<#= "<"+renderClass.Name+">" #>(_page);


Post A Comment
Title:
Name:
Email:
Comment:
Verification: