Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Note: This blog has moved to omervk.wordpress.com.

Omer van Kloeten's Facebook profile

Omer has been professionally developing applications over the past 8 years, both at the IDF’s IT corps and later at the Sela Technology Center, but has had the programming bug ever since he can remember himself.
As a senior developer at NuConomy, a leading web analytics and advertising startup, he leads a wide range of technologies for its flagship products.

Get Firefox


powered by Dapper 

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

August 2008 - Posts

Announcing New C# 4.0 LINQ Features and Book

* Fabrice Marguerie, co-author of LINQ In Action, asked me to clarify that this post has absolutely nothing to do with their book and is simply meant in jest *

LINQ has been around for quite a while, making our lives easier with its short, declarative syntax. During talks in closed sessions, the persons behind C# have come up with some great plans for its next version, including some vast improvements to LINQ. The team wanted to make everyone's lives even better by introducing some ground-breaking features to it.

I'd like to introduce, out of those finalized or at the final draft stage, some of the new keywords that have been introduced to the language with regards to LINQ and by doing so, expose the reader to this new, exciting technology.

fine

Many of the lines of code incorporated into LINQ are about variable validation. How many times have you had to write pieces of code like this:

var values = from n in numbers
where n > 0 && n < 10
select n;

This piece of code is very trivial and the compiler is smart enough to understand it on its own. From C# 4.0, the fine keyword is introduced and the above query will be replaced with:

var values = from n in numbers
where n is fine
select n;

 

some

Most LINQ queries do not iterate over an entire enumeration. Some filter out results, some use Take, Skip and other methods in order to run on only a subset of the elements. Since this is an extremely common scenario, the team has decided to integrate it into the language using the new some keyword:

var values = from n in some numbers
select n;

This is complemented with the new most keyword, which is like some, only it takes more elements.

somewhere

Global Warming vs. LINQ from Clauses The from clause is known to all who use LINQ, as it indicates the source of the data. Since this clause is a recurring pattern (statistical surveys have shown it to occur 99% of the time, allowing for a 4% standard deviation), the team behind the new language features has decided to cut it out, thus removing unnecessary verbosity from the language. This, in turn, will cause less characters to be written and rewritten, meaning less keystrokes, less keyboard wear, less purchases of new keyboards, leading to prevention of global warming, a goal near to Microsoft's heart. You can see Microsoft's predictions for this in the graph to the right.

This is possible due to the new somewhere keyword, as described below:

var values = from somewhere
select n;

This feature relies heavily upon the newly introduced Type Inference Transfer System (abbreviated MANTA), a technology recently demonstrated by Microsoft Research.

The Book

LINQ InactionI've long since wanted to write a book about something. Since this is just the tip of the iceberg, I've decided to write my book about this subject. It will contain most of what I know (hey, I still need to speak about something at conferences and release a second edition some day, right?) about the new language. I think that with all of the new features, making our lives as developers that much easier, I've picked an appropriate title.

Here's an excerpt from the introduction:

Recent advances in compilation technologies have brought with them less need for verbosity. In its stead come smart compilers, which infer much of the work for the developer. With such technology, there's not a lot you, as a developer, need to do anymore. You can simply write a short statement, validate its correctness, check the code in and go home for the day.

Welcome to the world of tomorrow. Put your feet up.

Here's the layout of the book, as I plan it:

  1. Introduction
  2. New Features in LINQ

What else would you like to see in the book? Let me know and I might just send you a copy of the rough draft for review once I finish it.

Posted: Aug 29 2008, 01:12 PM by Omer van Kloeten | with 13 comment(s)
Filed under: ,
Throw Before You Yield

In a comment left by Bart De Smet, he pointed out that I failed to address the fact that the execution of all "yielding" methods is deferred.

For instance, when running the following code, no exceptions will be thrown:

int[] arr = null;
var copy = arr.Enumerate();



// ...

static IEnumerable<T> Enumerate<T>(this IEnumerable<T> enumeration)
{
// Check to see that enumeration is not null
if (enumeration == null)
throw new ArgumentNullException("enumeration");

foreach (var item in enumeration)
{
yield return item;
}
}

This is because the first time the code from the method will run will be after there a call to copy's GetEnumerator(), followed by a call to that object's MoveNext() method has been made (i.e. when we enumerate over copy).

To overcome this problem, we'll change the code slightly:

static IEnumerable<T> Enumerate<T>(this IEnumerable<T> enumeration)
{
// Check to see that enumeration is not null
if (enumeration == null)
throw new ArgumentNullException("enumeration");

return EnumerateCore(enumeration);
}

private static IEnumerable<T> EnumerateCore<T>(IEnumerable<T> enumeration)
{
foreach (var item in enumeration)
{
yield return item;
}
}

Now a NullReferenceException will immediately be thrown out of Enumerate, since the "unyielding" method will first run the code and then defer-call to the "yielding" method. This helps our "yielding" methods adhere to the principal of fail-fast.

Posted: Aug 25 2008, 10:23 PM by Omer van Kloeten | with 5 comment(s)
Filed under:
MSDN Wiki?

Instructional Objectives by Davina DeVries, CC-BY I just love the fact that there's a "Community Content" section to the MSDN documentation. I just found out that there's an undocumented exception coming from the System.Net.Mail.MailMessage.Subject property, I browsed to the relevant MSDN page and simply added a line saying so.

It's a nice copy of the features from PHP's Documentation, but about 10 years too late, and also, mind you, not a Wiki at all. It's comments. In a real Wiki, my corrections to the documentation would be displayed inline with the original documentation. You know, like Wikipedia. Dear Microsoft, please turn it into a real Wiki, at which time your documentation will retain its relevance for me.

On a side note, does anyone know of an add-in for Visual Studio that replaces F1 to a call to Google in my default browser?

Pitfall: Static Field Inline Initialization Order of Execution
Lean by Katayun, CC-BY-NC-SA Here's something I fell into today. You have a class that has some members that need to be calculated once. So you use static readonly fields. One of those members is a calculation of some of those members. Take the following code for instance:
public class StaticDemo
{
    static readonly int Sum = A + B;
    static readonly int A = Calculator.GetA();
    static readonly int B = Calculator.GetB();
}

This code will initialize A and B from the Calculator class and initialize Sum from the sum of A and B. However, when you run this code, Sum will equal 0, no matter what A or B are.

Why is this? Apparently, when initializing static fields inline, the order of execution is from top to bottom, regardless of dependencies. Trying to use the same method to initialize an instance field will result in the error A field initializer cannot reference the non-static field, method, or property.

So how do we solve this, you ask?

public class StaticDemo
{
    static readonly int A = Calculator.GetA();
    static readonly int B = Calculator.GetB();
static readonly int Sum = A + B;
}
Now Sum will really equal the sum of A and B. Simple, but a sure-fire pitfall if you don't know it.
Posted: Aug 19 2008, 05:09 PM by Omer van Kloeten | with 9 comment(s)
Filed under:
Extension Methods Roundup: Intersect, Union, AsNullable and GroupEvery

Here we go with the third installment of the Extension Method Roundup. The reason behind these 'code dumps' is that LINQ is a central part of my coding and always find new problems I want to find elegant solutions to. Hope these prove as useful to you as they do to me.

Intersect / Union

Again, shorthand for when you have Enumerable of Enumerable of T and you simply want to intersect or union all of the enumerations in one single call.

public static IEnumerable<T> Intersect<T>(this IEnumerable<IEnumerable<T>> enumeration)
{
    // Check to see that enumeration is not null
    if (enumeration == null)
        throw new ArgumentNullException("enumeration");

    IEnumerable<T> returnValue = null;

    foreach (var e in enumeration)
    {
        if (returnValue != null)
            returnValue = e;
        else
            returnValue = returnValue.Intersect(e);
    }

    return returnValue;
}

public static IEnumerable<T> Union<T>(this IEnumerable<IEnumerable<T>> enumeration)
{
    // Check to see that enumeration is not null
    if (enumeration == null)
        throw new ArgumentNullException("enumeration");

    IEnumerable<T> returnValue = null;

    foreach (var e in enumeration)
    {
        if (returnValue != null)
            returnValue = e;
        else
            returnValue = returnValue.Union(e);
    }

    return returnValue;
}

AsNullable

I was always missing this method, to coincide with the Cast and OfType methods.

public static IEnumerable<T?> AsNullable<T>(this IEnumerable<T> enumeration)
    where T : struct
{
    return from item in enumeration
           select new Nullable<T>(item);
}

GroupEvery

This takes count items from an enumeration and groups them into a single array.

public static IEnumerable<T[]> GroupEvery<T>(this IEnumerable<T> enumeration, int count)
{
    // Check to see that enumeration is not null
    if (enumeration == null)
        throw new ArgumentNullException("enumeration");

    if (count <= 0)
        throw new ArgumentOutOfRangeException("count");

    int current = 0;
    T[] array = new T[count];

    foreach (var item in enumeration)
    {
        array[current++] = item;

        if (current == count)
        {
            yield return array;
            current = 0;
            array = new T[count];
        }
    }

    if (current != 0)
    {
        yield return array;
    }
}

I've also gone and updated my LINQ Extensions project on CodePlex with everything I've published since the last update. You're welcome to download and fiddle with it. :)

More Posts