views:

109

answers:

4

Hi,

I have a small dummy project in VS 2008, contains only the following code file

using System;

namespace FrameworkTest
{
    internal static class MessageQueueNative
    {
     struct TestStructure
     {
      public IntPtr aStatus;
     }

     public static void Main()
     {
      TestStructure pMgmtProps = new TestStructure { aStatus = IntPtr.Zero };
     }
    }
}

The project is set to target framework 2.0, even set the ToolsVersion to 2.0 manually in the project. Now the project is building just fine from VS and fails from command line (using csc.exe 2.0).

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\FrameworksTest.exe /target:exe Class1.cs Properties\AssemblyInfo.cs

Now the question is why does it compile from VS? It should fail as it does in case of cmd line compile. The same source fails (correctly) in VS2005 project.

Thanks, florin

+1  A: 

You're using a C# 3 compiler feature (the type initializer for TestStructure), thats why the code does not compile using csc from the command line (you're using v2) or from VS2005. My guess is VS2008 uses v3 of the C# compiler no matter which version of the framework you target, it just disables the features supported only by the newer versions of the .NET Framework.

If you change

TestStructure pMgmtProps = new TestStructure { aStatus = IntPtr.Zero };

to

TestStructure pMgmtProps = new TestStructure();
pMgmtProps.aStatus = IntPtr.Zero;

it should compile with all versions. Does seem like a bug though... interesting find...

Rory
It's not a bug, it's a feature. Seriously.
Lucero
+3  A: 

Multitargeting means CLR-version-targeting, not C#-version-targeting.

Michael Damatov
And the CLR is version 2 for .NET 2.0 through .NET 3.5. There's no re-versioning of the CLR until .NET 4.
Cylon Cat
+1  A: 

Initializers like that are a C# 3.0 compiler feature, not a .NET platform feature. This was by design.

consultutah
+1  A: 

VS2008 always uses the C# 3 compiler, which allows you to use the newer syntax (in your sample the initializer). Since this is purely syntax of the language, the compiler can still target V2 of the framework, which is what the target actually does. You'll be able to run the generated output on a computer with V2 of the framework only.

This is intentional and is also why solutions such as LinqBridge (LINQ-to-Objects implementation for .NET 2) do work as expected (and make sense).

Use MSBUILD from VS2008 to build the solution and you'll get consistent results.

Lucero
How do you compile directly with MsBuild from VS?Thanks,florin
florin
Sorry, I wasn't very exact with my wording. What I meant is to use the same MSBUILD version as VS2008 does, which is the one from the .NET Framework V3.5, usually found here: `C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe`
Lucero