7

I am working in VS2015 on a project which targets .Net framework 4.5

In the Build settings the language version is set to 'default'

As I've read, the C# 6 is only added in .Net 4.6, but I AM allowed (at least, the code compiles and runs) to use the string interpolation feature, which I've read is a C# 6 feature.

Now I am confused: am I now compiling for C# 6 / .Net 4.6 or for .Net 4.5 (and how could I check that?)

EDIT

In the comments I see that C# 6 syntax has nothing to do with the .NET framework version. I got the idea from this answer (What are the correct version numbers for C#?) where is said 'C# 6.0 released with .NET 4.6 and VS2015 (July 2015).' so I understood that C# 6 is (somehow) coupled to .NET 4.6

Community
  • 1
  • 1
Michel
  • 21,571
  • 43
  • 141
  • 223
  • 3
    C# 6.0 syntax is interpreted by the compiler, it has nothing to do with the Framework. If you use VS2015, its compiler is up to the task – Steve Sep 05 '16 at 08:14
  • 1
    This is just syntactical sugar which... After compilation the CLR should be the same.. – Constantin Treiber Sep 05 '16 at 08:15
  • @user3185569 I've read that item, but that does not answer my question – Michel Sep 05 '16 at 08:15
  • 1
    @ConstantinTreiber this is not entirely correct, but as long as you dont use`FormattableString` I agree. .net 4.6 has a new feature called `FormattableString` read :http://stackoverflow.com/a/34859921/5962841 for further information. Normally you shouldn't care about this tho. – Mafii Sep 05 '16 at 09:29
  • @Steve also read my comment – Mafii Sep 05 '16 at 09:30

2 Answers2

7

C# 6 features such as string interpolation are compiler features, not runtime (CLR) features. Therefore, you can use them regardless of what version of .NET you are building against, as long as your compiler supports C# 6.

In Visual Studio 2015 you can control which version of the language you are targeting in Properties => Build tab => Advanced button => Language Version

RB.
  • 33,692
  • 12
  • 79
  • 121
  • Ok, so when I've read string interpolation is a C# 6 feature, that is not true? – Michel Sep 05 '16 at 08:17
  • @Michel It is true, but the compiler changes it to `String.Format`, so It can run normally on .NET 4.5. – Zein Makki Sep 05 '16 at 08:17
  • And the compiler version; what determines the version I use? Is that just the version of VS I use? – Michel Sep 05 '16 at 08:17
  • @Michel The compiler ships with Visual Studio. For example if you need to use C# 6.0 Compiler when running VS 2012, you need to add a Nuget Package as VS 2012 doesn't ship with C# 6.0 compiler : https://www.nuget.org/packages/Microsoft.Net.Compilers/ – Zein Makki Sep 05 '16 at 08:20
  • Copying my comment from above: @user3185569 this is not entirely correct, but as long as you dont use `FormattableString` I agree. .net 4.6 has a new feature called `FormattableString` read :stackoverflow.com/a/34859921/5962841 for further information. Normally you shouldn't care about this tho. – Mafii Sep 05 '16 at 09:31
3

Generally, new versions of the C# compiler are released at the same time as new versions of the .Net Framework. But the C# compiler does not depend on the version of the Framework you're using, instead it depends on specific types and members being present. Those types are included in the new framework, but they can also come from somewhere else.

For example, this is why you can use C# 5.0 async-await on .Net 4.0, using the Microsoft.Bcl.Async package.

Specifically for C# 6.0, basic string interpolation does not require any new types or members, so it doesn't need new framework version. This code:

string s = $"pie is {3.14}";
Console.WriteLine(s);

Compiles to:

string s = string.Format("pie is {0}", 3.14);
Console.WriteLine(s);

Which works just fine on .Net 4.5.

On the other hand, one advanced feature of string interpolation is that the interpolated string can be converted to IFormattable or FormattableString. For example, this code:

IFormattable formattable = $"pie is {3.14}";
Console.WriteLine(formattable.ToString(null, CultureInfo.InvariantCulture));
Console.WriteLine(formattable.ToString(null, new CultureInfo("cs-CZ")));

Compiles to:

IFormattable formattable = FormattableStringFactory.Create("pie is {0}", 3.14);
Console.WriteLine(formattable.ToString(null, CultureInfo.InvariantCulture));
Console.WriteLine(formattable.ToString(null, new CultureInfo("cs-CZ")));

This compiles fine on .Net 4.6, but fails on .Net 4.5 with:

error CS0518: Predefined type 'System.Runtime.CompilerServices.FormattableStringFactory' is not defined or imported

But you can make it compile by including the following code:

namespace System.Runtime.CompilerServices
{
    class FormattableStringFactory
    {
        public static IFormattable Create(string format, params object[] args) => null;
    }
}

Of course, with this dummy implementation, the following code will throw a NullReferenceException.

You can actually make it work by referencing the unofficial StringInterpolationBridge package.

svick
  • 214,528
  • 47
  • 357
  • 477