05 January 2008

Visual Studio 2008 multi-targeting: using C# 3.0 for your .NET framework 2.0 apps

A friend recently told me he was curious about how it would be possible to use the C# 3.0 compiler to compile applications targeting the .NET 2.0 framework, and this while leveraging the new C# 3.0 features. Indeed, there are no reasons why the 2.0 framework and runtime would have any issues to run C# 3.0 applications, as long as they reference only assemblies from the 2.0 framework. This is because all new C# 3.0 language features were implemented at the compiler level, thus not requiring any change to the runtime (there is no newer runtime than the 2.0).


So I did a quick test with VS 2008, and I was pleased to notice that this indeed works like a charm. At first, I thought that multi-targeting also meant using the compiler corresponding to the target framework, but apparently, VS 2008 always compiles your source files using the C# 3.0 compiler, even when you're targeting another framework than 3.5.


A quick example: the following code


using System;
using System.Collections.Generic;

namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var foo = 2;
Console.WriteLine(foo);
List<int> fooList = new List<int>() { foo, foo++, foo++ };
foreach (var x in fooList)
Console.WriteLine(x);
Console.ReadLine();
}
}
}


gets compiled into IL, and Reflector shows the equivalent C# 2.0 syntax of the Main method:



private static void Main(string[] args)
{
int foo = 2;
Console.WriteLine(foo);
List<int> <>g__initLocal0 = new List<int>();
<>g__initLocal0.Add(foo);
<>g__initLocal0.Add(foo++);
<>g__initLocal0.Add(foo++);
List<int> fooList = <>g__initLocal0;
foreach (int x in fooList)
{
Console.WriteLine(x);
}
Console.ReadLine();
}


Of course, the above example only uses some of the new C# 3.0 features (type inference and collection initializers), and using LINQ will require adding references to.NET framework 3.5 assemblies (System.Core.dll and System.Data.Linq.dll). Even if you decide to recreate LINQ yourself from scratch, which is perfectly possible, you'll need at least a reference to System.Core.dll because of extension methods that require the System.Runtime.CompilerServices.ExtensionAttribute.


Here's a summary table of new C# 3.0 features that can actually be used in .NET 2.0 applications.


C# 3.0 Feature

Supported on .NET Framework 2.0?

Local Variable Type Inference

Yes

Object Initializers

Yes

Collection Initializers

Yes

Anonymous Types

Yes

Auto-Implemented Properties

Yes

Extension Methods

No (needs ExtensionAttribute in System.Core.dll)

Query Expressions

No (needs Extension Methods)

Expression Trees

No (needs IQueryable in System.Core.dll)

Implicitly-Typed Arrays

Yes

Lambda Expressions

Yes

Partial Methods

Yes



As a conclusion, even if you're still stuck with .NET 2.0 as your runtime environment, you can already leverage some C# 3.0 features in your code. And VS 2008 supports it!

No comments: