views:

117

answers:

5

I had a VS2005 solution and wanted to get off VS2005 for the new year. I was mostly happy with the upgrade process and pleasantly surprised to see that my build scripts mostly still worked.

My question is around the multi-targeting feature - I don't have .NET 3.5 installed on my servers, so I have to continue to target .NET 2.0. That worked, mostly, but I found that I could do things like

var returnMe = "result: " + result.ToString();

...and still debug the project successfully.

When I got that code up to the build server, the build failed, saying that "var" wasn't defined.

So, which should I be expecting?

  1. VS2008, targeting .NET 2.0, should throw errors when I try to do C# 3 things
  2. the build server, being aware that I'm targeting .NET 2.0, should understand what I'm doing and compile the thing into a 2.0-compatible binary

Any ideas?

A: 

When you use Visual Studio 2008 to target the 2.0 runtime, you are still using the 3.0 version of the C# compiler to compile your code. The CLR runtime itself did not change much between 2005 and 2008. It is in fact just a service pack to the core CLR and the addition of several new libraries (System.Core.dll in particular).

So the majority of the features added in 2008 work just fine on the 2.0 runtime. This is completely legal and if you attempt to use a feature which does not work in 2.0 you will encounter an error either at build time or publish time.

JaredPar
+5  A: 

The problem appears to be that the build server does not have the right compiler. You can build it on your workstation, right?

Many of the .NET 3.0 "features" are just syntax bits that revert to CLR 2 code at compile time. var is one of them -- when it compiles, the compiler converts var to the appropriate type.

There is a pretty informative post on this at http://weblogs.asp.net/shahar/archive/2008/01/23/use-c-3-features-from-c-2-and-net-2-0-code.aspx

Jay
will you look at that...<tasks><msbuild><executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>[...]I bet this would work if I pointed at a different MSBuild... thanks
dnord
A: 

If you want to target a specific build you can do this via configuration settings (which is exactly what I've just been reading up for 70-536 exam, very dry stuff!).

Add something like the following in your app.exe.config file

<configuration>
   <startup>
      <requiredRuntime version="v2.0.50727"/>
   </startup>
</configuration>

You can then force all your builds to use the same version regardless of the machine, should help you to force the debugging to use the correct version too.

Ian
A: 

If you don't use the following libraries/technologies:

  • Windows Presentation Foundation (WPF)
  • Windows Communication Foundation (WCF)
  • Windows Workflow Foundation (WWF)
  • Windows CardSpace (WCS)

then you are more or less on the safe side, although I would recommend thorough testing anyway.

You're able to use .Net 3.0 features like var etc. just because VS2008 doesn't care about target version of the framework when it comes to things like on-the-fly syntax checking, IntelliSence and probably others. And as far as I know VS2010 will pay attention on these things, which will prevent you from successfull compiling your "var x = ..." constructions when targeting 2.0 framework version.

Igor Korkhov
A: 

As others have said, C# 3.0 features can be used when targeting the .NET 2.0 runtime with the C# 3.0 compiler.

A little known fact related to this is that you can even use LINQ with .NET 2.0 if provide your own LINQ implementation.

Here's an example that enables the 'select' and 'where' operators:

namespace System.Runtime.CompilerServices
{
    // defining this attribute allows using extension methods with .NET 2.0
    [AttributeUsage(AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute {}
}

namespace System
{
    public delegate R Func<A, R>(A arg0);
}

namespace System.Linq
{
    public static class Enumerable
    {
        public static IEnumerable<R> Select<T, R>(this IEnumerable<T> input, Func<T, R> f)
        {
            foreach (T element in input)
                yield return f(element);
        }

        public static IEnumerable<T> Where<T>(this IEnumerable<T> input, Func<T, bool> f)
        {
            foreach (T element in input) {
                if (f(element))
                    yield return element;
            }
        }
    }

You could ship Mono's version of System.Core with your application if you want to make full use of LINQ on .NET 2.0.

Daniel