7

I use the .NET 4 (not .NET 4.5 or any other version of the framework!)

Why different versions of Visual Studio will output different result of the same code using the SAME .NET Framework?

I have the following

static void Main(string[] args)
{
    var values = new List<int>() { 1, 2, 3, 4, 5 };
    var funcs = new List<Func<int>>();

    foreach (var v in values) {
        funcs.Add(() => v * 10);
    }

    foreach (var f in funcs) {
        Console.WriteLine(f());
    }

    Console.ReadKey();
}

In Visual Studio 2013 the output is 10 20 30 40 50 (Target .NET v == 4).
In Visual Studio 2010 the output is 50 50 50 50 50 (Target .NET v == 4).

Where is the problem? How to identify the C# (not the .NET!) version used by each Studio for the .NET 4

C:\Windows\Microsoft.NET\Framework\v4.0.30319>csc /?
Microsoft (R) Visual C# Compiler version 4.0.30319.33440
for Microsoft (R) .NET Framework 4.5

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>csc /?
Microsoft (R) Visual C# Compiler version 4.0.30319.33440
for Microsoft (R) .NET Framework 4.5

C:\Program Files (x86)\Microsoft Visual Studio 12.0>csc /?
Microsoft (R) Visual C# Compiler version 12.0.30110.0
for C# 5

EDIT

Can I say that

VS 2010 == C# 4
VS 2013 == C# 5

and this independently of the target framework of the concrete solution?

serhio
  • 28,010
  • 62
  • 221
  • 374
  • I display the output of `csc /?` on my machine – serhio Apr 02 '14 at 13:05
  • I think it's explained in [Has foreach's use of variables been changed in C# 5?](http://stackoverflow.com/questions/12112881/has-foreachs-use-of-variables-been-changed-in-c-sharp-5). – Andrew Morton Apr 02 '14 at 13:07
  • @Habib not a duplicate. my question is **why different Visual Studio targeting the same .Net outputs different result** – serhio Apr 02 '14 at 13:07
  • @serhio, the main reason is because Visual studio 2013 uses C# 5.0 compiler by default. That is why the duplicate linked question. – Habib Apr 02 '14 at 13:09
  • @Habib When I target the .NET 4 framework, it also uses the C# 5 compiler? – serhio Apr 02 '14 at 13:10
  • @serhio, See [Untangling the Versions By Jon Skeet](http://csharpindepth.com/articles/chapter1/versions.aspx) – Habib Apr 02 '14 at 13:11
  • The answer is no, reference assemblies are used. And VS 2010 doesn't work with .Net 4.5 reference assemblies, so you can't compile .Net 4.5 application using VS 2010. – Ofiris Apr 02 '14 at 13:11
  • Yes, target framework doesn't change the compiler used. – Damien_The_Unbeliever Apr 02 '14 at 13:11
  • 3
    @serhio Yes, if you targeted .NET 2.0 it would still use the C# 5 compiler. The compiler version and the framework version are totally independent of each other. The compiler version is decided by which version of VS you use but it is fixed and the framework version is settable by project. – Scott Chamberlain Apr 02 '14 at 13:11
  • 1
    The question is now wrong. 2013 automatically installs framework 4.5.1 and targets that automatically – Amit Joki Apr 02 '14 at 13:12
  • @Ofiris, forget about **.NET 4.5, I don't use it** in this example – serhio Apr 02 '14 at 13:14

1 Answers1

9

From Eric Lippert's blog post:

In C# 5, the loop variable of a foreach will be logically inside the loop, and therefore closures will close over a fresh copy of the variable each time.

And a quote from MSDN:

Visual Studio 2010 will not let you develop using C# 5. The new C# 5 language features are part of the compiler, and will be included in the Visual Studio 2012 compiler. Even if you install .NET 4.5, this will not let you take advantage of the new features of the language (such as async/await), as these require a new compiler to use.

VS2013 works with only C# 5.0 compiler and you can target various .NET frameworks. Because of this, you use get C# 5.0 features like async/await and still target .NET 4.0.

Ofiris
  • 6,047
  • 6
  • 35
  • 58
  • When I target VS **2013** to the **.NET 4** framework, it also uses the C# 5 compiler? – serhio Apr 02 '14 at 13:11
  • 3
    @serhio: Yes, right. VS2013 works with only C# 5.0 compiler and you can target various .NET frameworks. Because of this, you use get C# 5.0 features like `async/await` and still target .NET 4.0. – YK1 Apr 02 '14 at 13:16
  • 1
    Added the comment to the answer, very relevant. – Ofiris Apr 02 '14 at 13:21
  • ok, but how about my CSC output? it says that it uses the C# 4?? – serhio Apr 02 '14 at 13:26
  • Where do you run it from ? for VS2013, use `All programs --> VS2013 --> VS Tools -> Dev Command --> csc` – Ofiris Apr 02 '14 at 13:30
  • @Ofiris as you can see in the post, I run it from `C:\Windows\Microsoft.NET\Framework\v4.0.30319>csc /?` – serhio Apr 02 '14 at 13:32
  • @YK1 I tried but I can't use the async/await targeting .net 4, because not al types used by async await are present in that framework. – serhio Apr 02 '14 at 13:33
  • 2
    @serhio: To get the required types for `async/await`, add NuGet package Microsoft.Bcl.Async. See http://stackoverflow.com/questions/22060691/how-microsoft-bcl-async-works – YK1 Apr 02 '14 at 13:36
  • VS 2013 uses the C# compiler v12(!) (for C#5), but VS 2013 does not even indicate the c#version used, just the compiler version 4... (see my edit) – serhio Apr 02 '14 at 13:42
  • @serhio: .NET 4.5 is just marketing name like Windows Vista is actually Windows vesion 6.0 and Windows 7 is actually version 6.1. Actual version of C# compiler and other system assemblies like clr.dll for .NET 4.5 is `4.0.30319.17929` and greater. The version 13.0 is more related to ToolsVersion of msbuild. From VS2013 onwards microsoft will ship msbuild with Visual Studio - unlike before where msbuild shipped with .NET framework releases. – YK1 Apr 02 '14 at 13:45
  • I don't know if is "more related" or not, but I see the difference between the C# **compiler** version and the **C#** (?!) version, the **.NET** version, and also **VS** version... a mess... – serhio Apr 02 '14 at 13:48
  • 1
    @serhio: Yes, C# version is marketing name. C# compiler version is internal version - which they can update/hotfix. They cannot hotfix marketing names. I don't see what is your confusion. Anyway, one correction, VS2013 toolsVersion is 12.0 - not 13.0. – YK1 Apr 02 '14 at 14:06