I’ve just squeezed out a couple of hours to install and try Visual Studio 2008 today. There were two surprises that came with that:
- Unpleasant - Resharper does not fully support .NET 3.5 (it almost hurts). It is planned to have R# 4.0 release around 2008 Q1.
- Pleasant - Some .NET 3.5 compiler and syntax sugar features work with .NET 2.0.
Let me expand on the last item. These .NET 3.5 features work with .NET 2.0:
- local variable inference
- anonymous types
- object initializers
- extensions methods
- query expressions
- lambda expressions
In other words, this code does compile in Visual Studio 2008 when .NET 2.0 framework is targeted:
public static class Program
{
static void Main(string[] args)
{
List<Customer> customers = new List<Customer>
{
new Customer{Name="Bob", Age=23},
new Customer{Name="Donald",Age=10}
};
var query = from c in customers
where c.Age > 11
select c.Name;
query.Print();
}
public static void Print<T>(this IEnumerable<T> collection)
{
foreach (T item in collection)
{
Console.WriteLine(item);
}
}
}
public class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
To make this happen you just need to add the following namespace and class declarations:
namespace System
{
public delegate TRes Func<TSrc, TRes>(TSrc src);
}
namespace System.Runtime.CompilerServices
{
public class ExtensionAttribute : Attribute { }
}
namespace System.Linq
{
public static class Enumerable
{
public static IEnumerable<TSrc> Where<TSrc>(
this IEnumerable<TSrc> source, Func<TSrc, bool> predicate)
{
List<TSrc> res = new List<TSrc>();
foreach (TSrc s in source)
{
if (predicate(s))
{
res.Add(s);
}
}
return res;
}
public static IEnumerable<TRes> Select<TSrc, TRes>(
this IEnumerable<TSrc> source, Func<TSrc, TRes> selector)
{
List<TRes> res = new List<TRes>();
foreach (TSrc s in source)
{
TRes t = selector(s);
res.Add(t);
}
return res;
}
}
}
And if you remove the code above (i.e.: using C# preprocessor directive #if), and switch then target framework to .NET 3.5, the program will still compile.
It is sweet, is not it?
If this works as it is expected I’d be glad to have those features in .NET 2.0 projects. This will help to produce more efficient code.
Update: In the next post I’ll explain how to compile autofac project (it extensively uses lamda expressions and extensions) against .NET 2.0. And there’ll be some compatibility code in a single file.
Update: alternatively you can use LinqBridge library to compile against .NET 2.0 or simply manually reference System.Core.dll (requires editing of project file).

3 Responses to “How to use .NET 3.5 syntax and compiler features for .NET 2.0?”