DCSIMG

 Subscribe in a reader

September 2007 - Posts - Guy kolbis

September 2007 - Posts

Visual studio Orcas and C# 3.0 introduce some very cool features. Recently I have been working on several posts that talk about those new features. I recommend you all to review them:

In this post I will be discussing on yet another cool feature: Lambda Expressions.  

Overview

C# 2.0 introduced a new feature, anonymous methods, that allows you to declare your method code inline instead of with a delegate function:

            FileSystemWatcher watcher = new FileSystemWatcher(@"c:\");

            watcher.Changed += delegate(object sender, FileSystemEventArgs e)
            {
                //do something...
            };

As you can see, I did not create a method to handle the Change event, instead I use an inline declaration for the method handler.

Lambda Expressions

An expression is a set of language elements combined to perform a meaningful computation.

C# 3.0 introduces an even simpler syntax, lambda expressions, which you write as a parameter list followed by the "=>" token, followed by an expression or a statement block. This feature simplifies coding delegates and anonymous methods.

            Person p1 = new Person(){ ID = 1, IDRole = 1, FirstName = "guy", LastName = "kolbis" };

            //with delegation:
            Func<Person, bool> f = p => p.ID == 1;
            bool res = f(p1);

In this example, I have created a delegation that gets a Person as input parameter and returns bool. The delegation will check if the Person's ID equals to 1. The delegation is compiled into executable code and we can invoke it later on. As you can see, this is fairly simple.

You can also use the delegation with multi parameters:

            Func<Person, Person, bool> f2 = (person1, person2) => person1.LastName == person2.LastName;
            res = f2(p1,p2);

You can also query an IEnumerable<T>:

            List<Person> people = new List<Person> 
            {
                new Person(){ ID = 1, IDRole = 1, LastName = "Anderson", FirstName = "Brad"},
                new Person(){ ID = 2, IDRole = 2, LastName = "Gray", FirstName = "Tom"}
            };

            people.Where(p => p.ID == 1).Select(p => new { p.FirstName, p.LastName });

Summary

Lambda expressions provide a simple way to write inline code blocks where delegates are expected. Their behavior is strikingly similar to anonymous methods. In fact, they are syntactic sugar in terms of syntax.

Extension methods is a new feature introduced by Orcas. As the name implies, the idea behind the extension method is to extend existing types with new methods.

Getting Started

Creating an extension method is fairly simple. For example, lets say that for each string type, you would like to add a new method that will convert white spaces into underscores:

        public static string SpaceToUnderscore(this string source)
        {
            char[] cArray = source.ToCharArray();
            string result = null;
            foreach (char c in cArray)
            {
                if (Char.IsWhiteSpace(c))
                    result += "_";
                else
                    result += c;
            }
            return result;
        }

For those of you with the sharp eyes, you might have noticed that the method must be declared as static and that the input parameter proceeds by the keyword "this". When doing so, we actually tell the compiler that this is an extension method for type string. Now, we can use the extension simply by adding a reference to the assembly where we defined it and adding the appropriate namespace.

            string str = "Extension methods overview by Guy Kolbis";
            str.SpaceToUnderscore();

Linq

My main motivation for exploring the extension method feature was another new feature named Linq. It all began by simply exploring the List<T> type.

            List<Person> people = new List<Person> 
            {
                new Person(){ ID = 1, IDRole = 1, LastName = "Anderson", FirstName = "Brad"},
                new Person(){ ID = 2, IDRole = 2, LastName = "Gray", FirstName = "Tom"}
            };

When I created a new list of type List<Person> I have noticed something strange. I could actually see several method signatures that originaly should not belong to the List<T> implementation:

image

The "Where", "Select" and others methods have been added to that type.

You may wonder how this is possible. C# 2.0 doesn’t provide these methods for the List<T> class. Moreover, LINQ runs on .NET 2.0 and installing LINQ doesn’t replace any .NET 2.0 assemblies.

So, after reading the fine prints I have noticed two things:

1) image - The Icon indicates an "extension method".

2) image - The documentation indicates that this is an extension method.

Now, lets go back to Linq. When we query an IEnumerable<T> we use enhancements to the C# languages, for example:

            var query = from p in people
                        where p.ID == 1
                        select new { p.FirstName, p.LastName };

When the compiler finds a query expression, it will convert it to method calls:

            var query = people.
                            Where(p=>p.ID == 1).
                            Select(p=>new {p.FirstName,p.LastName});

The from keyword has been removed, leaving just the collection, people, against which to perform the query. The where and select clauses are transformed into two method calls: Where<T>() and Select<T>(), respectively. They have been concatenated so that the Where method’s result is filtered by the Select method.

This would have not be possible without the extension methods.

Visual Studio 2008 introduces a host of new features and enhancements that dramatically improve the experience of software developers. You can all attend this 8-part Web seminar series and learn about the next generation development environment for the Microsoft Windows platform & exciting new technologies coming in Visual Studio 2008.

You can find the seminars here.

Lately I have been working on a design for a web application. For that application I was going to use .NET 3.5 features, which includes WCF, Linq, XLinq, Linq to Sql and WF.

My Data layer had to reside on a windows service which exposes WCF services. One requirement I had to implement was a fail over scenario. In other words a load balancer that can redirect requests to an active data layer.

For example: lets say I installed three data layers (each one is a windows service), and there are ten clients that addresses those data layers. Suddenly, one of my data layer crushes and all the clients that addressed that specific layer will start getting exceptions.

image

N clients (web applications) with 3 data services holding the data layer.

So, I was looking for a solution that will be able to select a responsive data layer.

Microsoft had released scenario samples for WCF that include a router sample, which demonstrates how to implement a service that provides basic routing and load balancing functionality.

That was exactly what I was looking for.

In Visual Studio Orcas we get a new feature named "automated properties". Shortly put, instead of writing:

private string _firstName;
    
    public string FirstName
    {

        get
        {
            return _firstName;
        }
        set
        {
            _firstName = value;
        }
    }

you can write:

public string FirstName
    {
        get;
        set;
    }

You can read more about it here.

Sometimes, I still want to create a property and a private field in the old way and to do so I am used to invoke the prop snippet. However this is not the case. When you use the prop snippet, you will get the second implementation. So here is a code snippet that will generate the old property:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>prop</Title>
            <Shortcut>prop2</Shortcut>
            <Description>Code snippet for property and backing field</Description>
            <Author>Microsoft Corporation</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>Property type</ToolTip>
                    <Default>int</Default>
                </Literal>
                <Literal>
                    <ID>property</ID>
                    <ToolTip>Property name</ToolTip>
                    <Default>MyProperty</Default>
                </Literal>
                <Literal>
                    <ID>field</ID>
                    <ToolTip>The variable backing this property</ToolTip>
                    <Default>myVar</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[private $type$ $field$;

    public $type$ $property$
    {
        get { return $field$;}
        set { $field$ = value;}
    }
    $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

You still need to add this snippet using the Snippet Manager.