Download the Orcas March CTP now

Wed, February 28, 2007, 04:25 AM under Orcas | VisualStudio
Finally, I can empty my queue of Orcas draft blog posts :-)
Get the installable bits here and the VPC image here.

1st March: Updated with screenshot.

Vista week on Channel9

Wed, February 28, 2007, 04:23 AM under Windows | Vista
More Vista content added to channel9 throughout the week. Watch it here.

Fully booked with UK in-person events over the next 3 weeks

Tue, February 20, 2007, 05:38 AM under Events
If you are a developer in the UK, this is my speaking schedule for the next 3 weeks, and the reason I cannot attend any other matters:
  • Today (20 Feb) I am travelling up to Nottingham to do a talk tomorrow (21 Feb) on LINQ.
  • On Thursday (22 Feb) I travel to Wales to do an academic tech talk on Windows Mobile development the following day (23 Feb).
  • Next week (26 Feb – 1 Mar) I am attending DevWeek in London and presenting there on Vista development (28 Feb).
  • Next Friday (2 Mar) I travel to Glasgow for an event on Monday (5 Mar) again on LINQ.
  • The following day (6 Mar) I travel to Wales for a 2-day internal offsite where I am doing a small piece on Vista.
  • When I return, I travel to Heathrow (8 Mar) for a two day DevFest event where I am delivering both Vista and .NET Compact Framework presentations.
  • The week after, I travel to Harrogate (12 Mar) to do yet another session on LINQ (13 Mar).
  • The following day (14 Mar), I am doing another Windows Mobile tech talk at Manchester Metropolitan University.
  • BTW, all three LINQ sessions above are part of the MSDN roadshow (additionally on 21 Mar in London and 27 Mar & 25 Apr in Reading).

Phew! In short, for the next 22 days I am constantly travelling, talking/demoing or prepping (contrary to some beliefs, these sessions don't just deliver themselves with no prepartion on slides/demo/timings!).

LINQ Resources

Tue, February 20, 2007, 04:37 AM under dotNET | Orcas | LINQ
In order to really understand LINQ and before moving to LINQ to data/xml/etc, one has to appreciate the features that LINQ builds on and how LINQ to objects works (unless you like to think of it as magic :)).

To that end I suggest you read my blog entries in order:
1. LINQ
2. Local Variable Type Inference (and the VB version)
3. Object Initiliasers
4. Anonymous Types
5. Extension Methods
6. Lambda Expressions (and the VB version)
7. Decomposing LINQ (includes Query Expressions)

My 1 hour talk on LINQ is coming to a city near you (if you live in the UK) and my code-littered slides are available to download here (pptx format).

If you want to play with LINQ you need Orcas. You can get the May CTP of last year or the January CTP from this year but to be brutally honest, namespaces/syntax/features have changed so the one you really really want is the Feb/March CTP so I would wait for that one which is just round the corner.

For even more info, see the following links:
- Official LINQ page
- We have some screencasts here and channel9 has some media here.
- Plenty of blogs with LINQ or C#3 or VB9 categories and some of them are here, here, here, here, here and here.
- For more, search.

For all your questions, as usual the msdn forums offer free support so please go there.

Decomposing LINQ

Sun, February 18, 2007, 07:04 PM under dotNET | Orcas | LINQ
Please revisit the example from my previous post on LINQ. Here I only include the query snippet of code:
       var results =
from p in Process.GetProcesses()
where p.Threads.Count > 6
select new {p.ProcessName, ThreadCount = p.Threads.Count, p.Id };
...or in VB if you prefer:
    Dim results = _
From p In Process.GetProcesses() _
Where p.Threads.Count > 6 _
Select New With {p.ProcessName, .ThreadCount = p.Threads.Count, p.Id}
The above is based on a number of new language features including one that I have not mentioned until now: query expressions. If we were to take away query expressions, the code above would look like this:
   var results =
Process.GetProcesses()
.Where(p => p.Threads.Count > 6)
.Select(p=>new {p.ProcessName, ThreadCount = p.Threads.Count, p.Id });
In VB:
    Dim results = _
Process.GetProcesses() _
.Where(Function(p) p.Threads.Count > 6) _
.Select(Function(p) New With {p.ProcessName, .ThreadCount = p.Threads.Count, p.Id})
The two snippets above are identical. There isn't much more to explain about Query Expressions other than... that is the way it is! The two code snippets above are identical, the first one using query expression syntax to beautify the real code shown in the 2nd one.

So let's look at the 2nd snippet more closely. The first line (Process.GetProcesses()) returns an array and we know that arrays implement IEnumerable. Well it turns out that in Framework 3.5 there are some extension methods for IEnumerable including a method called Where that takes as an argument a delegate (named Func) and returns an IEnumerable. This extension method (along with other extension methods) and the delegate it accepts (along with other delegates) are in the System.Linq.Enumerable class that is in Core dll.

Given what we just said, the second line above (.Where(p => p.Threads.Count > 6)) should make a lot more sense now: the way we pass in a delegate to the Where extension method is by using a lambda expression (VB lambda link). The 3rd line of code is also straightforward once you know that another extension method on IEnumerable is Select. It also takes a delegate and we used a lambda expression for that as well. Note how in the body of the lambda we use anonymous types. What Select returns is a generic IEnumerable of the anonymous type we create on the fly. Since we cannot write compilable code of an IEnumerable of an anonymous type, we use local variable type inference (VB inference link) for the results variable and again take advantage of inference when we want to access each element:
      foreach (var o in results)
{
Console.WriteLine(o.ToString());
}
Note that if you look closely at the extension methods in Enumerable and the delegates in the System.Linq namespace, you will find extreme usage of generics and that is how that code can deal with arbitrary conditions, anonymous types etc that are used in LINQ queries. Don’t forget the compiler magic of course that does generate quite a bit of goo in addition to the code you write. For that last point, compile the code above and open the assembly with reflector and you'll see what I mean :-)

To finish off, take a glance at the original query without the query expression syntax; what would the code look like if we also took away all the new language features (but still using the new Enumerable class of the Framework 3.5)? First we have to write two extra methods and declare a helper class):
    private class MothAnonymousType
{
public string ProcessName;
public int ThreadCount;
public int Id;
//
public override string ToString()
{
return "{ ProcessName = " + ProcessName + ", ThreadCount = " + ThreadCount + ", Id = " + Id + " }";
}
}
private static bool MothWhere(Process p)
{
return p.Threads.Count > 6;
}
private static MothAnonymousType MothSelect(Process p)
{
MothAnonymousType type1 = new MothAnonymousType();
type1.ProcessName = p.ProcessName;
type1.ThreadCount = p.Threads.Count;
type1.Id = p.Id;
return type1;
}
and then our calling code changes to this:
    static void Main(string[] args)
{
IEnumerable<MothAnonymousType> results =
Enumerable.Select(
Enumerable.Where(Process.GetProcesses(), new Func<Process, bool>(MothWhere)),
new Func<Process, MothAnonymousType>(MothSelect));
//
foreach (MothAnonymousType o in results)
{
Console.WriteLine(o.ToString());
}

Console.ReadLine();
}


I think I prefer the original query syntax don’t you ;-)

Lambda Expressions in VB9

Sun, February 18, 2007, 06:54 PM under dotNET | Orcas | LINQ
This short blog entry assumes that you have read my description of C# lambda expressions and here I will literally just show you the proposed VB syntax that corresponds to the lambda we ended up with in that blog post: i => i > 2. The corresponding syntax is: Function(x) i > 2

So, the full example, given the following code:
  Delegate Function SomeDelegate(ByVal i As Integer) As Boolean
Public Sub SomeMethod()
'
'REMEMBER FROM LAST TIME, THE KEY LINE IS THE FOLLOWING
Dim sd As SomeDelegate = New SomeDelegate(AddressOf OtherMethod)
'
' other code here
YetOneMore(sd)
End Sub
Private Function OtherMethod(ByVal i As Integer) As Boolean
Return i > 2
End Function
Private Sub YetOneMore(ByVal f As SomeDelegate)
Dim res As Boolean = f(5)
Console.WriteLine(res.ToString())
End Sub
We can get rid of the OtherMethod method completely and inline on the delegate creation line using the VB9 lambda expression sysntax, like this:
    Dim sd As SomeDelegate = Function(i) i > 2

WARNING: for this feature only and for the VB case only, I do not have a compiler that supports it yet. Unlike all my other blog posts, I am basing the above on a spec rather than hands on experience. If I find that it changes when I get new bits, I will come back here and update this.

Lambda Expressions C# 3.0

Sun, February 18, 2007, 06:48 PM under dotNET | Orcas | LINQ
There are two aspects to lambda expressions and I will only discuss one of them in this post. The aspect not discussed is the one that is most useful, but to get there we must first understand the syntax, which follows.

Lambdas are simply shorthand to creating a delegate and pointing it to a method plus they offer type inference. Consider the following C# example:
delegate bool SomeDelegate(int i);
public void SomeMethod()
{
SomeDelegate sd = new SomeDelegate(OtherMethod);
//
// other code here
YetOneMore(sd);
}
private bool OtherMethod(int i)
{
return i > 2;
}
private void YetOneMore(SomeDelegate f)
{
bool res = f(5);
Console.WriteLine(res.ToString());
}
Nothing complicated (or useful) takes place. Before I rewrite it using a lambda expression, let's re-write it a bit using C# 2.0 anonymous methods:
delegate bool SomeDelegate(int i);
private void SomeMethod()
{
SomeDelegate sd =
delegate(int i){return i > 2;}
;
//
// other code here
YetOneMore(sd);
}
private void YetOneMore(SomeDelegate f)
{
bool res = f(5);
Console.WriteLine(b.ToString());
}
If you are not familiar with anonymous methods, basically we have inlined OtherMethod by using the delegate keyword.

Lambda expressions take this to the next level of conciseness.
This line:
    delegate(int i){return i > 2;}
can be written like this:
    (int i) => { return i > 2;}
so all we've done there is replace the delegate keyword with the funny syntax =>

However the beauty is that given the body only has a single return statement, we can make it even more concise *and* get the compiler to infer the parameter type:
 SomeDelegate sd = i => i > 2;
And that is the basics of lambdas: it looks weird, it is concise and it does some inference for us. In the future I will post about the other aspect of lambdas which is actually what most people are excited about: lambdas bound to parameter expressions.

Extension methods C# 3.0 and VB9

Sun, February 18, 2007, 06:43 PM under dotNET | Orcas | LINQ
How many times have you written wrapper methods for objects that in reality you wished were part of the object itself? For example, if you find yourself checking in multiple places if a string is all uppercase, you may write a wrapper method for it, e.g.:
namespace Helper
{
public static class StringHelper
{
public static bool IsAllUpper(string s)
{
//implementation left as an exercise to the reader
}
}
}
...or in VB if you prefer:
Namespace Helper
Public Module StringHelper
Public Function IsAllUpper(ByVal s As String) As Boolean
'implementation left as an exercise to the reader
End Function
End Module
End Namespace
...which you then call like this (assuming the Helper namespace is in scope):
string s = ...
bool itIs = StringHelper.IsAllUpper(s);
In VB:
Dim s As String = ...
Dim itIs As Boolean = StringHelper.IsAllUpper(s)
...when really, what you want is something more readable like this:
bool itIs = s.IsAllUpper();
In VB:
Dim itIs As Boolean = s.IsAllUpper()
That is exactly what extension methods let you do. To achieve that, a new attribute has been introduced: System.Runtime.CompilerServices.ExtensionAttribute (in System.Core.dll).

In the VB example above, simply add the Extension attribute to the method in the module:
    <Extension()> _
Public Function IsAllUpper(ByVal s As String) As Boolean
...
In c#, there is a shortcut to using the attribute which makes the following two represent the same thing:
[Extension()]
public static bool IsAllUppercase(string s) {...}

public static bool IsAllUppercase(this string s) {...}
...except the C# compiler will not let you write the first version and will instruct you to use the "this" keyword instead (a bit like it doesn't let you write an explicit finalizer method and instead instructs you to use destructor syntax).

So, back to our example, if in the c# case we simply insert the this keyword before the string argument in the IsAllUpper helper method (and in the VB case insert the Extension attribute before the method) then we can indeed type s.IsAllUpper() and the compiler is happy. In fact, the advantage of doing this is that intellisense will help you by showing the method when you type a dot after the variable thus making the helper method much more discoverable than what it would be today - see the following screenshot for how it distinguishes extension methods from normal methods by sticking an arrow in front:


Please note the following points which hopefully help answer any questions you might have:
0. It is not by accident that I chose a static class in C# and a module in VB. Those are the only places where you can define extension methods.
1. The compiler generates the longhand version: no magic is taking place here at runtime. Since you are not *really* adding a method to the class, you can only access public members of the object (e.g. only public members of the string in our example) from your extension method. It also follows that extensions are available to subclasses of the class you are extending.
2. For an extension method to be visible/applicable/in scope, you must import the namespace it resides in. So in our example, if you do not stick a using Helper; (or in VB Imports Helper) at the top of the file where you make the call, the extension method would not show up in intellisense and would not compile.
3. If two namespaces with extensions methods that have the same name are brought into scope, a compile error occurs; hence the usefulness of the previous point.
4. If you add to the object a real method that has the same name as the extension method, the real method takes precedence and your extension method is silently ignored.
5. Extension methods for properties are not possible.

Overall, I like this feature *a lot* (will post some concrete examples of why in the future). My only worry is that some devs will get lazy and use extension methods rather than inheritance when the latter is more applicable... time will tell.

Anonymous Types in C# 3.0 and VB9

Sun, February 18, 2007, 06:38 PM under dotNET | Orcas | LINQ
Recall local variable type inference (and the VB9 story) and object initialisers? Here is a reminder:
var o = new SomeType(); //inference
SomeType o = new SomeType {SomeField=DateTime.Now, AnotherField=5.6}; //initialisers
We can of course combine them:
var o = new SomeType {SomeField=DateTime.Now, AnotherField=5.6};
...or in VB if you prefer:
Dim o = New SomeType With {.SomeField = DateTime.Now, .AnotherField = 5.6}
Now, imagine that you were only using variable o in a single method. Also imagine that the type of o (SomeType) only has public fields/properties and no other methods/functions. Also imagine that SomeType was not used anywhere outside that single method. I know all this requires vivid imagination but humour me and picture that scenario.

Well, in the imaginary scenario, you really don't need to declare/define the type! Think about it, why would you need to know what type o is? All you need to be able to do is create something that looks like it and access the public fields/properties. That is exactly what the “anonymous types” feature offers:
var o = new {SomeField=DateTime.Now, AnotherField=5.6};
In VB:
Dim o = New With {.SomeField = DateTime.Now, .AnotherField = 5.6}
In the code above, the compiler generates a class for us, which is visible in IL. The name of the type is not visible to our code and the name is not otherwise usable. Hence we call the feature: anonymous types. If you use your favourite disassembler you can see what the name of the type is but that information will be of academic value.

Another featurette of anonymous types is that the compiler can infer the field names so if you amend the code above like this:
var o2 = new {DateTime.Now, AnotherField=5.6};
In VB:
Dim o2 = New With {DateTime.Now, .AnotherField = 5.6}
...then the anonymous type will have a property called Now that has the value of DateTime.Now and this will of course show up in intellisense e.g. Console.WriteLine(o.Now);

Also note that anonymous types override the ToString method and return something sensible in the format “{Field1 = value1, Field2 = value2}”

Of the three new language features that I've described so far, anonymous types looks like the most useless. Stick with this one for a while. When I bring it all together for LINQ, you'll see the usefulness of the feature.

Object Initializers in C# 3.0 and VB9

Sun, February 18, 2007, 06:36 PM under dotNET | Orcas | LINQ
How many times have you created an object and immediately started setting properties on it? For example, wherever I create a Thread object I use the following almost boilerplate snippet:
Thread myThread = new Thread(MyThreadMethod);
myThread.Name = "my thread";
myThread.IsBackground = true;
..or in VB if you prefer
    Dim myThread As New Thread(AddressOf MyThreadMethod)
myThread.Name = "my thread"
myThread.IsBackground = True
With object initialisers, you can combine the first 3 statements into one like so:
Thread myThread = new Thread(MyThreadMethod) {Name="my thread", IsBackground=true};
In VB:
Dim myThread As New Thread(AddressOf MyThreadMethod) With {.Name = "my thread", .IsBackground = True}
So, object initialisers is a feature that lets you assign public properties (and public fields) straight after the constructor in braces, without having to repeat the object variable name and type separate statements.

Note that the compiler generates the long hand code. For example, when you type the following statement:
TextBox t = new TextBox {Text="Hi", Multiline=true, Location = new Point(5,5), Size=new Size(50,100)};
In VB:
Dim t As New TextBox With {.Text = "Hi", .Multiline = True, .Location = New Point(5, 5), .Size = New Size(50, 100)}
...the compiler generates IL similar to if you typed:
      TextBox t = new TextBox(); 
t.Text = "Hi";
t.Multiline = true;
t.Location = new Point(5, 5);
t.Size = new Size(50, 100);
This feature saves you some typing and results in more concise code. While I like object initialisers, their full usefulness will become apparent when combined with the language enhancement that we look at next.

Option Infer in VB9

Sun, February 18, 2007, 06:30 PM under dotNET | Orcas | LINQ
I will assume here that you have read the narrative to my C# post about local variable type inference and build on it to discuss the VB syntax.

The VB syntax for local variable type inference is:
Dim i = 3
Dim s = "hi"
Dim o = New SomeType()
...which the compiler generates as:
Dim i As Integer = 3
Dim s As String = "hi"
Dim o As New SomeType()
Note that for reference types, you are not really saving a lot of typing compared to C#. The example I used in that post was:
    Dim myCol = New Dictionary(Of Integer, SomeType)()
, which represents a saving of only one character in VB:
    Dim myCol As New Dictionary(Of Integer, SomeType)()
What is more important is that some VB developers will be thinking right now “So what? I could always type Dim o = whatever”. My answer is “Not if you turned Option Strict On”. Don’t forget what I wrote in the c# version: this is early binding. Like shown above, the compiler infers the type and generates it for you. At this point, the astute reader will have a question: “So if I turn off Option Strict, then what happens? The old behaviour or the new?”. To which my answer is “Excellent point, let’s talk about that :-)”.

There is a new option in VB9: Option Infer. Option Infer, like its cousins, can be turned on/off at the project level or at the code file level. If you have Option Strict Off, then whether a variable has the old behaviour or new is determined by the setting of Option Infer. This also means that, unlike c#, you can turn off local variable type inference even in the strongly typed world (by setting Option Strict to On and then Option Infer to off). I believe the default for new VB projects will be that Option Infer is On.

There is a good opportunity here for all that VB6 code you ported over to .NET land and did not want to revisit with Option Strict On. If you turn Option Infer On, the code that did work, will now work faster. The code that had issues, will still have issues (for that you must still turn option Strict On).

Anyway, back to our syntax, the following example shows how to get variable inference in the For Each case like I showed before in C#:
    Dim col As IEnumerable(Of SomeType) = New SomeCollectionType()
For Each a In col 'a is inferred by the compiler to be SomeType
a.MethodOnSomeType() 'intellisense here pops-up as expected
Next
In the code above, the variable a is inferred by the compiler to be SomeType. Of course, if you turn Option Infer Off, then you will get a compiler error even with Option Strict Off. The only way not to get a compiler error for variable a is to turn Option Explicit Off too but we know that is just mad.

More language features follow!

Option Explicit and Option Strict in VB

Sun, February 18, 2007, 06:26 PM under dotNET
In VB you are always advised to declare all your variables since due to its heritage, VB allowed you not to declare a variable type, which is bad thing:
Sub Main
myVariableName = 6
myVariableName = myVariableNmae + 1

Debug.WriteLine(myVariableName)
End Sub
In the code above you were expecting myVariableName to be 7 when actually it is 1, the reason being that you misspelled your variable. Because you don't have to declare the variable, a new one was created for you when you misspelled it and of course it starts with a value of zero. Crazy world! Luckily, in VB6 and before, you could specify Option Explicit and that would not allow you to use variables without declaring them... phew. In .NET land with VB 7.0 by default Option Explicit On is specified for all projects but if people want to be stupid they can turn it off.

Another bad thing you could do in VB6 still remains today and that is the ability to declare untyped variables, for example:
Sub Main
Dim myVariableName = 6
myVariableName = myVariableName + 1
myVariableName = "hello"
Debug.WriteLine(myVariableName)
'
Dim o
o = New Collection
o.FeelingLucky
End Sub
Effectively, myVariableName is a Variant (or Object in .NET land) which means it can take any value you want and you never get a compile time error, instead you get a logical error. Similarly for variable o where the compiler cannot tell you that FeelingLucky is not a method of the Collection class so you get a runtime error/exception. So how can you escape this crazy world? A new option in VB 7.0 and beyond is Option Strict. Unfortunately, to this very day, you have to manually turn this option On yourself - it is not the default. If you haven't already, do it now for all your projects. You will prevent logical errors at runtime, runtime exceptions *and* you will make your code faster since method calls will be early bound rather than late bound.

Now, there are some niche scenarios where Option Strict Off may be convenient, namely when doing COM Interop with old automation models that are constructed in a certain way or if you have large codebase that already works and you do not want to touch it (hence you do not want to deal with the compile time errors that you will get when you turn option Strict On). The point here is that you can turn this option on/off at the file level. So I suggest that you turn it On at the project level and turn it off for the files that you think could do without the compile time checking.

Before I close this blog post, note that C# does not have either of these options which basically can be seen as that they are both On and you cannot turn them Off. While Option Explicit is useless, the convenience of doing easy late binding in VB with Option Strict Off can be cool. In c#, you have to do explicit late binding using reflection (which is what the VB compiler does for you in the VB case).

For much more on this topic use your favourite search engine i.e. like this or like that.

Local variable type inference in C# 3.0

Sun, February 18, 2007, 06:22 PM under dotNET | Orcas | LINQ
A new feature in C# version 3 that comes with Orcas allows you to declare variables within the body of a method like this:
var i = 3;
var s = "hi";
var o = new SomeType();
Note that the compiler generates IL that is identical to what it would generate if you typed:
int i = 3;
string s = "hi";
SomeType o = new SomeType();
In other words the 2nd line below compiles fine but the 3rd does not compile:
var b = true;
b = false; //fine
b = "pull the other one"; //Cannot implicitly convert type 'string' to 'bool'
So, the important point is that this local variable type inference, results in early-bound strongly-typed code. There is no late-binding taking place, besides the similarity with the var keyword in script languages where everything is an object/variant - that is not the case here.

Another point to stress is that variable inference does not work for class level fields or method arguments or anywhere else other than for local variables in a method.

Another example is the following:
IEnumerable<SomeType> col = new SomeCollectionType();
foreach (var a in col) //a is inferred by the compiler to be SomeType
{
a.MethodOnSomeType(); //intellisense here pops-up as expected
}
It is neat that the compiler can infer what type you expect a variable to be by looking at the right hand-side of the assignment, but I personally will not be using this often as I prefer explicitness. I guess it is a time saver for very long types, for example:
// I'd rather type this
var myCol = new Dictionary<int, SomeType>();
//...than type this
Dictionary<int, SomeType> myCol = new Dictionary<int, SomeType>();
Local variable type inference is a feature that seems not very useful in its own right, but becomes important when used in conjunction with other language enhancements.

Language INtegrated Query

Sun, February 18, 2007, 06:16 PM under dotNET | Orcas | LINQ
The biggest announcement at the last PDC was the LINQ project. It is now the headline feature of Orcas offered to all developers from web to client to device. Given that there are no changes to the runtime engine in Orcas, you will not be surprised to learn that LINQ is based entirely on compiler magic, the introduction of some fancy new syntax and some help from Core.dll.

LINQ simplifies querying objects, data and XML by integrating query and transform operations into the programming language (currently VB9 and C#3). It introduces a concise declarative syntax that is consistent irrespective of what your underlying data source is: in memory custom objects, datasets, XML, Entities etc. LINQ is also highly extensible which means that we are already seeing LINQ to other sources (e.g. search for blinq, plinq, linq to amazon, linq to WMI and so on).

I think that most devs will make most use of the LINQ-enabled ADO.NET (LINQ to SQL, LINQ to DataSet and LINQ to Entities) and of LINQ over XML. Before you start learning about those, it is my opinion you should learn about LINQ to objects first and then build on that.

Here is an example of some LINQ syntax:
    static void Main(string[] args)
{
var results =
from p in Process.GetProcesses()
select p;
//
foreach (var o in results)
{
Console.WriteLine(o.ToString());
}
//
Console.ReadLine();
}
This will output in your console a list of all the running processes on your machine in the following format "System.Diagnostics.Process (devenv)".

We can modify the query as follows:
        from p in Process.GetProcesses()
where p.Threads.Count > 6
select p;
...which unsurprisingly will trim the list to only show processes that have more than 6 threads.

We can modify the query further like so:
        from p in Process.GetProcesses()
where p.Threads.Count > 6
orderby p.ProcessName descending
select p;
...which due to the easily readable nature of linq, you can easily tell that it orders the resulting list of processes in descending order by the ProcessName (on my machine that puts the winlogon process at the top).

How about if I just want to see a few specific properties of each process (say Name, thread count and process id) ? Easily done by changing the query as follows:
        from p in Process.GetProcesses()
where p.Threads.Count > 6
orderby p.ProcessName descending
select new {p.ProcessName, ThreadCount = p.Threads.Count, p.Id };
...which on my machine produces this screenshot.

Finally, the Visual Basic syntax for the example above follows:
  Sub Main()
Dim results = _
From p In Process.GetProcesses() _
Where p.Threads.Count > 6 _
Order By p.ProcessName Descending _
Select New With {p.ProcessName, .ThreadCount = p.Threads.Count, p.Id}
'
For Each o In results
Console.WriteLine(o.ToString())
Next
'
Console.ReadLine()
End Sub
I think you get the idea: Picture the code you would have to write today to achieve the same results! The code above is easier to write, easier to read and maintain, and much more concise. Furthermore, because of its declarative nature, the compiler can perform any optimisations that it sees fit and is not restricted to your imperative solution (this is a promising aspect and one I'll revisit in the future). The other benefit is that the syntax you see above can be used to query XML and data as hinted at the beginning of this post. Again, you’ll hear more on that in a future blog entry.

The next step is to understand how the above funny syntax really works and that is the subject of my following blog entries available right now :)

Hilarious!

Thu, February 15, 2007, 03:24 PM under Links
Still ROTFL with ".NET Love" part 1 and part 2. :-D

NETCF 3.5 Headliner Features

Thu, February 15, 2007, 03:06 PM under MobileAndEmbedded
Over the last two posts I enumerated additions to the .NET Compact Framework 3.5, and there will be more posts as more Orcas CTPs come out. In particular, the two headline items of NETCF 3.5 are not listed at all in my previous two blog entries and they are: Compact WCF and Compact LINQ.

1. I have mentioned before Compact WCF. It is not in the January CTP, but when it does appear I’ll let you know.

2. LINQ is a topic that I’ll be talking a lot more about with regards to the full framework 2.5. Once I've written a few posts on that, I will come back to indicate what is missing from Compact LINQ [1].

The best people to describe the headline features and focus areas of the NETCF 3.5 are the Compact Framework team of course and they have done so here.

Cheers
Daniel

[1] If you are familiar with LINQ already, note that in the Jan “Orcas” CTP the NETCF LINQ bits use the old namespaces (e.g. System.Query ) in line with the May 2006 LINQ CTP rather than move on to the new System.Linq namespace. They are obviously aligned in future versions. Namespaces aside, the Compact LINQ implementation largely lives in System.Core assembly like its big brother.

More NETCF 3.5 Additions

Wed, February 14, 2007, 04:56 AM under MobileAndEmbedded
All the API additions I listed in my previous .NET Compact Framework 3.5 post, are namespaces/types/members that were already present in the full dotnet Framework v2.0 and are now also part of the NETCF 3.5

Here I will list a couple of additions that are brand new:

* When querying the Platform property of the static OSVersion property of the System.Environment class, we get back the PlatformID enumeration. NETCF 2.0 had a smaller list than the full framework and now with 3.5 not only it catches up by adding the Unix value but it even goes further by adding a brand new value: Xbox (not a surprise if you read this).
If you ask me, the full framework team should also add this enumeration value for code compatibility.

The other addition is entirely specific to device development and hence lives under the Microsoft.WindowsCE.Forms assembly. The SystemSettings class gets a new property (to make a grand total of 2!) named WinCEPlatform that returns the homonymous enumeration which has 3 values: WinCEGeneric, PocketPC and Smartphone
(I guess we’ll have to learn to map those last two to WM6 professional and standard :-p)

Next I'll list the real headlines of NETCF v3.5

.NET Micro Framework SDK

Tue, February 13, 2007, 06:19 AM under MobileAndEmbedded
Hot from the factory, get it here.


Just like the WM6 SDK, works fine on Vista on top of VS2005 SP1 as the screenshots show.

NETCF 3.5 API additions

Mon, February 12, 2007, 01:23 PM under MobileAndEmbedded
The next version number of the .NET Compact Framework is 3.5, compared to version number 2.0 that ships today. This is so the version numbers can align with v3.5 of the full framework (NetFx3.5). You can play with NETCF 3.5 in the Orcas Jan CTP.

Below is some new NETCF stuff that I found (v3.5.6282.0):

* Remember the EventWaitHandle class that I wrote 2 years ago? It is now part of the compact framework (System.Threading). As part of the addition, the inheritance hierarchies have changed so AutoResetEvent and ManualResetEvent now inherit from EventWaitHandle and not WaitHandle (making this blog entry half-obsolete :)).

* Remember the Stopwatch class that I wrote? It is now in the CF (System.Diagnostics).

* The Array class get the Resize method and some new Sort overloads.

* The CompilerGeneratedAttribute class from the System.Runtime.CompilerServices namespace is now added.

* The SerializationException class from the System.Runtime.Serialization namespace is added.

* System.Text.StringBuilder gets a new overload for the AppendFormat method and also both overloads of the AppendLine method.

* The System.Threading.Thread class gets the static MemoryBarrier method.

* The String class now contains the Contains method.

* A whole bunch of classes get a public Dispose method including GraphicsStream, FileStream, MemoryStream, StreamReader, StreamWriter, StringReader, StringWriter, TextReader, TextWriter and others.

* To support the next addition, the InvalidDataException class is added to the System.IO namespace in System.dll

* We get the entire System.IO.Compression namespace (i.e. GZipStream, DeflateStream, CompressionMode) from the System.dll

* Relevant to the previous addition, there is a new enum System.Net.DecompressionMethods that is the type of the new property AutomaticDecompression on the HttpWebRequest class.

* We get the entire System.Media namespace (SoundPlayer, SystemSound, SystemSounds) from the System.dll

* Mainly to support the previous addition, we get two classes in the System.ComponentModel namespace: AsyncCompletedEventArgs and AsyncCompletedEventHandler.

* The Trace class from the System.Diagnostics namespace only had 3 overloads of the Assert method. Now it becomes much more useful with 4 overloads for each of the methods Write, WriteIf, WriteLine and WriteLineIf. It also gets the Fail, Flush and Close methods. Add to that the new TextWriterTraceListener and tracing looks much better overall in NETCF v3.5

Stay tuned for more coming this week...

Windows Mobile 6 SDKs

Fri, February 9, 2007, 07:31 PM under MobileAndEmbedded
Remember, you heard/saw it here first!

It looks like the Windows Mobile 6 SDKs are out. Gone are the “for Pocket PC” and “for Smartphone” monikers. Instead, there is Professional and Standard... another mark of the convergence of the two form factors no doubt :-)


As you can see from the images in this post, the install works great on VS2005 SP1 on Vista!

UPDATE: When they are back online I’ll let you know. Please take your complaints here.
UPDATE 2: They are back online and I've updated the link above. Additional information here.

Windows Mobile 6

Thu, February 8, 2007, 02:30 AM under MobileAndEmbedded
I *think* engadget are the first to break the news that what was codename "Crossbow" is now officially Windows Mobile 6

Mel has the screenshots and links to reviews, Loke lists the developer features, Scott talks about the security improvements, John asks us to stay tuned for more and the Outlook Mobile team lists their favourite features .

Like Peter says, it will be hard to get devices in the early stages (typically takes 4-6 months), so the vast improvements in the emulator are most welcome.

Threading.ReaderWriterLockSlim

Wed, February 7, 2007, 04:16 PM under dotNET | Orcas
System.Threading is yet another namespace in System.Core.dll. There is only one main class in there: ReaderWriterLockSlim (don’t worry, System.Threading.ReaderWriterLock is still there in the mscorlib dll). The other types in the namespace are there just in a support role, including the LockRecursionPolicy enumeration and the LockRecursionException class. Joe has the details on ReaderWriteLockSlim here.

System.IO.Pipes

Wed, February 7, 2007, 03:39 PM under dotNET | Orcas
With a whole bunch of types, one of the biggest new namespaces in System.Core.dll is System.IO.Pipes (and support for it is required by types in other new namespaces in System.Core). Collectively the classes in there wrap their native counterparts to offer inter-process communication. You could achieve some IPC over named pipes in .NET remoting as I mentioned ages ago here. This new namespace in Orcas takes it to the next level and beyond and Justin has the full story here.

System.TimeZone2

Wed, February 7, 2007, 03:36 PM under dotNET | Orcas
Another namespace in System.Core.dll is System. It contains two exception classes (InvalidTimeZoneException and TimeZoneNotFoundException) and the TimeZone2 class (that further contains two types: AdjustmentRule and TransitionTime). Kathy has the details on TimeZone2 here.

System.Numeric.BigInteger

Wed, February 7, 2007, 03:33 PM under dotNET | Orcas
A new namespace in System.Core.dll is System.Numeric. There is a single type contained within, the BigInteger structure. Inbar has the details on BigInteger here.

System.Collections.Generic.HashSet

Wed, February 7, 2007, 03:31 PM under dotNET | Orcas
One of the namespaces in System.Core.dll is System.Collections.Generic with a single class HashSet (and its Enumerator of course). Kim has the details on HashSet here.

System.Core.dll

Wed, February 7, 2007, 02:45 PM under dotNET | Orcas
If you are looking for new stuff in the .NET Framework v3.5, you need to look at the new assembly System.Core.dll. NOTE: In the January CTP of Orcas you have to browse the file system in order to add a reference to it (i.e. navigate to C:\Windows\Microsoft.NET\Framework\v3.5.11209\). In future CTPs, it will be added by default to NetFx3.5 projects.

There are a whole bunch of namespaces in System.Core.dll from System and System.Diagnostics to System.IO and System.Security etc (but none named System.Core). Quite frankly, I’d prefer to see the namespaces/types move to where their friends are in mscorlib.dll, system.dll etc. I strongly doubt this will happen in the short term though given the desire to leave existing assemblies with no modifications.

In other words, System.Core.dll is your main “green” assembly, while the older ones are “red”. For more on the green and red bits in Orcas read these blog entries here and here.

Open Folder in Windows Explorer in Orcas

Wed, February 7, 2007, 04:33 AM under Orcas | VisualStudio
I discovered a small new feature in the Visual Studio “Orcas” IDE which I am already finding useful.

How many times have you had a Visual Studio solution open and you wanted to quickly open Windows Explorer and navigate to the folder of the solution or maybe the folder of the project or maybe the build folder (e.g. Bin\Debug)?

What I used to do with VS2005 is open a code file, right click on its tab and select “Open Containing Folder” (don’t tell me you didn’t know about that one!) and then navigate up/down to go where I really wanted to be. In particular, many times I would “Show All Files” in Solution Explorer, then expand the bin\Debug folder, open the pdb file in VS just so I could right click on its tab and select “Open Containing Folder” (sounds long winded but is actually much faster than any alternative):


Now with Orcas, life becomes easier. Simply go to Solution Explorer select the solution node or the project node (or even a bin/obj folder if you have shown all files) and then... right click:

Notice just above “Properties” the new menu item “Open Folder in Windows Explorer”? It does exactly what you expect it to (and yes, I know that I am easily pleased :-D)

BTW, if you want to assign a shortcut key to the command (via Tools->Options->Environment->Keyboard), its name is ProjectandSolutionContextMenus.Project.OpenFolderInWindowsExplorer.

Windows Vista Sidebar Gadget articles

Mon, February 5, 2007, 03:03 PM under Windows | Vista
Out of all the work I’ve done over the past year, I get the most “thank you” notes for the screencast introducing Sidebar and gadgets. Many of the emails I receive include a request for more info on Sidebar gadget development.

In addition to the ones at the end of my Sidebar blog entry (in FAQ format), I usually point to two other articles, included here for future reference:
1. OdeToCode article.
2. UKStudentzine article (from a student on our team :)).

Lastly, I received an email from Danny Espinoza asking me to try their product. Even though the description looks interesting, I don’t have the time right now to play with it; maybe someone reading my blog will want to try out their widget converter.

For Sidebar gadget support questions, please use the dedicated forum.

Windows Mobile 5 Demo code

Sun, February 4, 2007, 04:04 PM under MobileAndEmbedded
A few people have asked me for the code I used in my WM5 Managed API screencasts (part one, two, and three). While I can’t find that exact code, it was almost identical to what I used in my Tech Ed session last year, which luckily I could find. You may download the VS2005 project here.

Mac adverts

Sun, February 4, 2007, 07:40 AM under Links
More often than not Sahil’s blog entries are written in a very entertaining style, so when I saw the title of his latest post I knew the content would make me smile: Hi, I'm a PC, and you're just a liar!! :-D

Rambling about WebDD

Sun, February 4, 2007, 07:05 AM under Random
As suggested two days ago, yesterday I was at WebDD to listen to some talks and do a 10’ stint myself.

I had a good time. It was basically a DDD with focused web content, and with a few additional twists including:
1. There was active presence by Microsoft (e.g. speakers, pods)
2. It was slightly smaller (3 rooms instead of 4)
3. No public voting of sessions
4. ScottGu dominated the event (His room was always full, with people standing and queuing)

As a complete aside, having attended (and presented) a few 1-day events at our UK TVP offices I think I prefer events where the two rooms (Chicago 1 & 2) are joined i.e. single track events.

I was one of the people standing in Scott’s sessions and I can see why people were so attracted to his talks (heck, I am not even into web development and I sat through 3 of them!):
a. Gravitas
When the General Manager of the developer platform is telling you how it is, you know that you are not only getting the facts, but also what decisions were made before reaching the current spec and what is waiting in the pipeline. You also know that you can give feedback straight to the horse’s... ears.
b. Geekness
I have always maintained that developers enjoy watching/listening to fellow geeks. Scott is a geek.
c. Passion
Usually, but not always, follows on from the previous point. In this case, it was evident that Scott was passionate about what he was showing.

Notice how I did not include in the list above “presentation skills”. That is because I have never heard so many times the word “um” in a session. If it wasn’t for the compelling content I would have walked out at one point in the “WPF/e” talk :-)

Speaking of presentation mistakes, on to my grok talk...
I managed to start talking and then realised that I had forgotten to connect my laptop to the projector... doh! I also hadn’t realised that the only microphone available was one that you must hold... a bit difficult when your entire talk is demo-based! Thanks to Richard, Dave and John for filling in for me while I battled to get Vista to talk to the screen and thanks for later holding the microphone to my face while I used the keyboard/mouse. Live and learn. As for the topic of my grok talk, I settled on Sidebar (apologies if you were hoping for SideShow, but I feel that it is hard to talk about it without having real hardware to show to people).

Grok talk at WebDD on Vista Gadgets

Fri, February 2, 2007, 07:05 AM under Events
Given that generally my focus is on client and mobile technologies, you wouldn’t expect to see me at a web event, but I want to catch Scott Guthrie’s “Sneak peak at Orcas” session, so tomorrow (Saturday) I will be at WebDD – say "hi" if you spot me :-)

They have some grok talks at lunch time and I’ve been pushed forward to do one. I entered the title of “Vista Gadgets”, which leaves the door open to talk about Sidebar or SideShow. I could try to cover both but in 10’ that would mean restricting it to an end user’s perspective rather than showing code for either of them... we’ll see what mood I am in tomorrow ;-)

In any case, don’t expect anything new from this grok talk, it will be a cut-down version of either the Sidebar screencast or the SideShow screencast. See you there!

WMDC RTM

Thu, February 1, 2007, 11:42 AM under Links
The replacement of ActiveSync on Windows Vista, the Windows Mobile Device Center has RTMd (only 3-4 months after my last WMDC post)!

Remember to remove any Beta you may have had and get download links from here.
(or wait for Windows Update by the end of the week with your phone plugged in as always).