Sun, May 13, 2007, 03:30 PM under
dotNET |
Orcas |
LINQ
For the importance and context of this blog entry, please
DO read
my previous blog post including the disclaimer at the top.
The feature I have not explicitly addressed yet is
extension methods. If you are a C# developer that has been using the "magic"
this keyword read my
explanation to understand what we are talking about here. You see, even though extension methods are a compiler trick, they do rely on the new System.Runtime.CompilerServices.ExtensionAttribute introduced in System.Core.dll. Since we've already established that System.Core is a Fx v3.5 assembly and hence is not usable from 2.0 projects, you might think this is the end of the road for extension method usage in 2.0 projects. Let's explore this further.
In a 2.0 Orcas project try and compile the following code:
static class Program
{
//[ExtensionAttribute()]
static void DisplayInterval(this Timer t)
{
Console.WriteLine(t.Interval.ToString());
}
static void Main(string[] args)
{
System.Timers.Timer t = new System.Timers.Timer(2000);
Program.DisplayInterval(t); // long hand usage of method
t.DisplayInterval(); // short hand usage of method (extension)
Console.ReadLine();
}
}
You will see a compiler error as follows:
"Cannot use 'this' modifier on first parameter of method declaration without a reference to System.Core.dll. Add a reference to System.Core.dll or remove 'this' modifier from the method declaration"
What the compiler *really* wants to say is:
"You are using the 'this' modifier and it depends on the ExtensionAttribute that itself resides in the System.Core.dll and you do not have a reference to it"
Once you understand what it is really saying, and once you realise that it only needs this attribute at compile time (since at runtime the IL to be interpreted will still include the call to the utility method in long hand), then it all becomes clear what you need to do next. Declare the attribute yourself! It isn't such a big logical jump (or else I wouldn't have made it :-))
So add to your 2.0 project a new empty code file and paste in it the following code:
namespace System.Runtime.CompilerServices
{
public class ExtensionAttribute : Attribute { }
}
Then, wherever you declare the extension methods, optionally add to the top:
using System.Runtime.CompilerServices;
Now your projects will compile and you can use extension methods!
So summing up the
previous post and this one, all 6 language features behind LINQ are usable from Fx v2.0 projects. But the LINQ to objects/xml/data implementations clearly are not usable because they live in Fx 3.5 assemblies. You can of course offer your own LINQ implementations for your own data sources. For example, the following code will compile in a Fx 2.0 project...
using Moth.Linq;
static class Program
{
static void Main(string[] args)
{
var ints = new []{1,2,3,4};
var res2 = from p in ints
where p > 2
select p;
System.Diagnostics.Debugger.Break();
// examine res2
Console.ReadLine();
}
}
...if you also add to the project
this (demo) code file here.
BTW, how soon are you guys out there planning to move your existing 2.0 projects to Visual Studio "Orcas"? ;-)
Sun, May 13, 2007, 03:15 PM under
Orcas |
VisualStudio |
LINQ
Please note that this and my next post are based on Beta 1 Orcas bits. Later builds might change the facts so always try it yourselves.There still appears to be some confusion with regards to the new language features that make LINQ to objects work. In particular, there are claims that it all works with .NET 2.0 and counterclaims that it doesn't. IMO the confusion arises from people not being precise about what they are talking about. I'll try and give you here my view (which of course I think is as clear as can get :-))
To start with, everything here is in the context of Visual Studio "Orcas" – forget earlier versions. Orcas supports
multitargeting so you can build projects that target .NET Framework v2.0. So the real question we are addressing here is whether you can choose to build a NetFx 2.0 project that also uses some of the new C#3 language features.
If you are not familiar with LINQ, please go read my detailed
LINQ blog posts and then come back. So after reading about LINQ I hope you realise that:
LINQ =
1. local variable inference +
2. object intiliazers +
3. anonymous types +
4. lambda expressions +
5. extension methods +
6. query expressions +
7. framework support.
Let's look at some of the language features. The first 4
do work with 2.0 projects i.e. the following compiles and runs fine in a 2.0 Orcas project:
class Program
{
delegate T Func<T>(T t);
static void Main(string[] args)
{
// object init -
// makes no sense in this example but hey...
Timer t = new Timer(2000)
{
AutoReset = false,
Enabled = true
};
// local var inf, anonymous types
var i = new { Name = "Fred", Age = 6 };
Console.WriteLine(i.ToString());
// lambdas
Func<int> f = j => j + 1;
Console.WriteLine(f(5));
Console.ReadLine();
}
}
Can you spot them?
Local variable type inference,
object initiliazers,
lambda expressions and
anonymous types. This shouldn't surprise you if you read my previous blog posts since I have stated clearly many times that these language features are simply compiler tricks. The IL that gets generated is the same old IL – no dependency on the framework and no dependency on the runtime. So 2.0 projects in Orcas can use 4 of the smart compiler tricks, this is good! As an aside, other 3.0 compiler features irrelevant to LINQ such as
automatic properties, also work in 2.0 projects.
On the gloomy side, it goes without saying that number 7 above, the "framework support", resides in
System.Core.dll and you cannot reference that assembly from 2.0 projects, so no
extension method implementations for you in 2.0 projects. If at this point we think of number 6 above, "query expressions" (i.e.
from...where...select syntax), we realise that their usefulness is in friendly mapping to the extension method implementations in System.Core.dll (or System.Xml.Linq or Systam.Data.Linq or your own extension method implementations). So even though query expressions are supported when targeting v2.0 projects from VS "Orcas" (the syntax highlighting when you try it is a clue) there is no implementation to map them onto - other than your own. Well, even your "own implementation" implies that you can use Extension methods for v2.0 projects and I haven't addressed that yet (number 5 above).
See my next post now.