20

I'm trying to run a new T4 template in Visual Studio 2015. However it fails to compile at this line:

var message = $"Linked table '{linkedTable}' does not exist.";

The compiler reports that the '$' character is unexpected. This syntax should however be valid in C# v6, according to the new string interpolation feature guidelines.

Is there a way to make the T4 templating engine use the newer C# version, other than to compile my code in an external library?

UPDATE:

Here are the declaration elements for the file, as a reference:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".sql" #>
<#@ SqlModelDirective processor="SqlModelDirectiveProcessor" #>

<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="Microsoft.SqlServer.Dac" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="Microsoft.SqlServer.Dac.Model" #>

Apart from the SqlModelDirective element this is pretty standard I think.

Crono
  • 10,211
  • 6
  • 43
  • 75
  • 1
    Can you post the "rest" of the T4? The beginning usually has directives that define the language, linkage, etc. – Eris Sep 10 '15 at 15:29
  • 1
    Can you use other C# 6 features in T4? String interpolation doesn't work on Razor pages even though other features work. Perhaps it's the same bug in T4. Both Razor and T4 are converted to C# code before compiling. A bug in that conversion could cause the wrong C# code to be generated when using string interpolation – Panagiotis Kanavos Sep 10 '15 at 15:35
  • @Eris I updated the post. – Crono Sep 10 '15 at 15:36
  • @PanagiotisKanavos Ahhh, I think you're on to something. I'm out to lunch right now but I'll investigate on this as soon as I get back. – Crono Sep 10 '15 at 15:37
  • Also, when you say fails to compile, does it fail to generate code using the T4, or is the generated code not compiling? – Eris Sep 10 '15 at 15:38
  • 1
    @Eris, the OP's template generates SQL. The compiler error almost certainly occurs in the template itself – Panagiotis Kanavos Sep 10 '15 at 15:40
  • First step I would do is set `debug="true"`, but from what I've seen in other questions is that T4 generation is "locked" in at C#4. It might be possible to set `language="C#6.0"` and add the appropriate references, but I don't have the facilities to test at the moment. – Eris Sep 10 '15 at 15:45
  • @Eris It's the template code that fails to compile, not the code it generates (in fact it doesn't generate any right now). – Crono Sep 10 '15 at 16:48

4 Answers4

16

You can't use C# 6 in T4 templates right now as they don't use the latest compiler.

You can specify compiler options in the compilerOption attribute of the template directive. If the latest compiler was used, you could use:

<#@ template debug="false" hostspecific="false" language="C#" 
    compilerOptions="/langversion:6" #>

When I tried this I got the following error:

Compiling transformation: Invalid option '6' for /langversion; must be ISO-1, ISO-2, 3, 4, 5 or Default

UPDATE

Found this discussion on the ASP.NET repository on Github. Seems the ASP.NET team is looking to replace T4 with Razor (which is not a bad idea BTW). Wonder if @davidfowl has more info ;)

UPDATE 2

David Fowler responded on Twitter - T4 uses CodeDom which hasn't been updated to use Roslyn yet. While there is a NuGet package with replacement CodeDom providers, it works only on ASP.NET 4.x projects, not T4.

So no C# 6 in T4 for now.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • I guess this means for the time being I must stick to `string.Format`... man, that hurts! Still, I got to learn about the `compilerOptions` attribute. It's something. Thank you so much! – Crono Sep 10 '15 at 16:55
  • This seems to be working now in VS2017 15.6.6, once you add the compiler options flag mentioned above. woo! – GotDibbs Oct 17 '18 at 17:22
10

You should upgrade to Visual Studio 2015 Update 2, released on March 30, 2016, which introduces such functionality. Under its “Other Changes”:

Enhanced T4 text templates so that they now support C# 6.0.

However, the functionality is broken again in Visual Studio 2015 Update 3.

Douglas
  • 53,759
  • 13
  • 140
  • 188
  • CTP is of size 5GB :O , it's like I'm download MSVS 2015 again :S , I thought it's just update of size around 20-50 mb :S – Angelus Mortis Feb 25 '16 at 18:29
  • 1
    update 2 has arrived with the promised C# 6 in t4 https://www.visualstudio.com/en-us/news/vs2015-update2-vs.aspx – TKharaishvili Mar 31 '16 at 19:32
  • @GwynBleidd: Thanks for the update. I've incorporated the new link into the answer. – Douglas Mar 31 '16 at 20:32
  • 2
    Really? I'm using VS2015 Update 3 and C# 6 features *still* aren't supported in T4 templates. – nathanchere Jul 27 '16 at 15:56
  • Looks like it doesn't work with VS2015 U3. Even with `compilerOptions` set to `/langversion:6` the T4 just won't compile. – Crono Jul 27 '16 at 20:36
  • @nathanchere: Confirmed; seems to be a regression bug in Update 3. I'm also experiencing another weird bug with T4 templates; hopefully they'll be patched in an update soon. – Douglas Jul 27 '16 at 21:25
  • Same here with the annoying feature of it not working in T4 either. Come on VS! – Richard Griffiths Dec 11 '17 at 11:57
2

In Visual Studio 2017 (and probably 2015 too), adding the latest Microsoft.Net.Compilers nuget package to the project containing your T4 templates will enable the latest C# features such as interpolated strings. (I have just done this using Visual Studio 2017 15.6.2 and version 2.7.0 of the package).

Chris Seed
  • 133
  • 2
  • 5
0

This was not working for me in Visual Studio 2019 so I resorted to creating a separate project that I referenced with an assembly directive. Essentially the assembly is a class feature block

user487779
  • 550
  • 5
  • 12