How to use .NET 3.5 syntax and compiler features for .NET 2.0?
Thursday, January 10, 2008 at 3:15 Tweet UPDATE: there is an updated version of this article.
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 (open source helper project Lokad Shared Libraries has this done).
Reader Comments (4)
[...] to compile all the mentioned code to target .NET 2.0 (as all the code from my code snippets compiles into). However, in this case I was not able to use the LinqBridge library since it does not have support [...]
[...] http://rabdullin.com/how-to-use-net-35-syntax-and-compiler-features-for-net-20/ [...]
[...] http://rabdullin.com/how-to-use-net-35-syntax-and-compiler-features-for-net-20/ © 2008 Scott Hanselman. All rights reserved. [...]
the System.Core.dll from compact framework 3.5 is usable from 2.0 full framework projects - makes all classes from system.linq available