Silverlight Feeds - All your Silverlight feeds in one place.

Sponsors

Tuesday, February 10, 2009

Extension Methods Part 2 – Lambda Expressions in Linq

by jesseliberty via Jesse Liberty - Silverlight Geek on 2/10/2009 3:21:00 PM

LeftLit



More: Extension Methods Part 1

In my previous entry on this topic I demonstrated how you can use Extension methods to add what appear to be new methods to existing classes. In this entry I will demonstrate how Extension methods enhance Linq by adding “method queries” using lambda expressions.

To see how this works, let’s set up a simple query,  with a display that will show the two ways we might execute that query using Linq.

We’ll start by creating a new Silverlight application and within the application a simple data class, Person. Here is the code for Person.cs

using System.Collections.Generic;

namespace ExtensionPart2
{
   public class Person
   {
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public string EmailAddress { get; set; }

      public override string ToString()
      {
         return string.Format( "{0} {1}\n{2}",
                     FirstName, LastName, EmailAddress );
      }

      public static List<Person> GetPeople()
      {
         List<Person> people = new List<Person>();
         people.Add( new Person() 
         { 
            FirstName = "Jesse", 
            LastName = "Liberty", 
            EmailAddress = "jliberty@microsoft.com" 
         } );

         people.Add( new Person() 
         { 
            FirstName = "George", 
            LastName = "Washington", 
            EmailAddress = "gWashington@whitehouse.gov" 
         } );



// also added John Adams, Thomas Jefferson
// James Madison, James Monroe, John Q. Adams return people; } } }

(I've elided the initialization of 5 of the presidents to save room)

 

We will issue two queries against this data. The first is a traditional Linq query,

from person in people
where person.LastName.StartsWith( "M" )
select person;

While this works fine, taking advantage of extension methods allows us (or more accurately the authors of the library) to extend the List<t> class to add the Where method, which in turn allows us to collapse these three statements to a single line of code using a lambda expression,

people.Where( person => person.LastName.StartsWith( "M" ) );

Examining the Extension Method

The tooltip for people.Where give great insight into what is actually going on here

whereExtension

Taking this apart, we see that Where is defined to be an extension method that returns an IEnumerable<Person> and takes one argument: a function (named predicate) that takes two arguments: a Person object and a boolean.

Rather than passing in a method, or a delegate to a method, or even an anonymous method, we go one step further and pass in a lambda expression. As you know from previous articles, the lambda expression "are a way to write short in-line substitutions for the methods that delegates refer to."

You can read the lambda expression above as

"There is a method that takes one parameter, a list of person objects named people and that returns  each person whose last name starts with the letter m in an IEnumberable collection."

or, more conventionally you can read it as

"person goes to each person whose last name starts with m"

For a lengthy review of how to read this aloud see this article.

The result for both queries is identical, but I would argue the second query is far more readable, as shown in the running program,

Extension2Running

The code for Page.xaml is shown here, and below it the code for Page.xaml.cs

Page.xaml

<UserControl x:Class="ExtensionPart2.Page"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d"
  HorizontalAlignment="Left"
  VerticalAlignment="Center"
  FontFamily="Georgia"
  FontSize="14"
  Width="650"
  Height="553"
  Margin="5">
  <Grid x:Name="LayoutRoot"
        Background="Bisque"
        Margin="20">
    <Grid.RowDefinitions>
      <RowDefinition Height="1*" />
      <RowDefinition Height="5*" />
      <RowDefinition Height="3*" />
      <RowDefinition Height="3*" />
      <RowDefinition Height="1.5*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="6*" />
      <ColumnDefinition Width="4.5*" />
    </Grid.ColumnDefinitions>
    <TextBlock Height="Auto"
               Width="Auto"
               Grid.Row="0"
               Text="Where last name begins with M"
               TextWrapping="Wrap"
               FontFamily="Georgia"
               FontSize="24"
               Margin="0"
               Grid.RowSpan="1"
               Grid.ColumnSpan="2"
               HorizontalAlignment="Center" />
    <TextBlock Text="Presidents"
               TextWrapping="NoWrap"
               FontFamily="Georgia"
               FontSize="18"
               HorizontalAlignment="Left"
               VerticalAlignment="Top"
               Margin="5,5,5,5"
               d:LayoutOverrides="Height"
               Grid.Row="1" />
    <ListBox x:Name="PresidentsListBox"
             Margin="5"
             Grid.Row="1"
             Grid.Column="1" />
    <TextBlock HorizontalAlignment="Left"
               VerticalAlignment="Bottom"
               Margin="5,4,5,5"
               Grid.Row="2"
               FontFamily="Georgia"
               FontSize="14"
               Text=""
               TextWrapping="Wrap" />
    <ListBox x:Name="LinqResults"
             Margin="5"
             Grid.Row="2"
             Grid.RowSpan="1"
             Grid.Column="1" />
    <ListBox x:Name="QOEM_Results"
             Margin="5"
             Grid.Column="1"
             Grid.Row="3"
             Grid.RowSpan="1" />
    <StackPanel Margin="0"
                Grid.Row="2">
      <TextBlock Height="Auto"
                 Width="Auto"
                 RenderTransformOrigin="0.5,0.5"
                 FontFamily="Georgia"
                 FontSize="18"
                 Text="from person in people"
                 TextWrapping="NoWrap"
                 HorizontalAlignment="Left" />
      <TextBlock Height="Auto"
                 RenderTransformOrigin="0.5,0.5"
                 FontFamily="Georgia"
                 FontSize="18"
                 Text="where person.LastName.StartsWith
                     (&quot;M&quot;)"
                 TextWrapping="NoWrap"
                 Width="Auto"
                 HorizontalAlignment="Left" />
      <TextBlock RenderTransformOrigin="0.5,0.5"
                 FontFamily="Georgia"
                 FontSize="18"
                 Text="select person"
                 TextWrapping="NoWrap"
                 Width="334"
                 Height="20"
                 HorizontalAlignment="Left" />
    </StackPanel>
    <StackPanel Margin="0,0,0,0"
                Grid.Row="3">
      <TextBlock x:Name="QOEM"
                 FontFamily="Georgia"
                 FontSize="18"
                 Text="people.Where ( 
    person =&gt; person.LastName.StartsWith ( &quot;M&quot; );"
                 TextWrapping="Wrap"/>
    </StackPanel>
    <Button x:Name="Go"
            Background="#FF00FF00"
            FontFamily="Georgia"
            FontSize="24"
            Foreground="#FF0000FF"
            Margin="5"
            Grid.Column="1"
            Grid.Row="5"
            Content="Go!" />
  </Grid>
</UserControl>

Page.xaml.cs

using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace ExtensionPart2
{
   public partial class Page : UserControl
   {
      public Page()
      {
         InitializeComponent();
         Go.Click += new RoutedEventHandler( Go_Click );
      }

      void Go_Click( object sender, RoutedEventArgs e )
      {
         List<Person> people = Person.GetPeople();

         // bind entire collection
         PresidentsListBox.ItemsSource = people;

         // traditional linq statement
         LinqResults.ItemsSource = from person in people
                            where person.LastName.StartsWith( "M" )
                            select person;

         // extended method
         QOEM_Results.ItemsSource = people.Where(
person => person.LastName.StartsWith( "M" ) ); } // end go button event handler } // end class } // end namespace

This work is licensed under a Creative Commons Attribution By license.
email it!bookmark it!digg it!

Original Post: Extension Methods Part 2 – Lambda Expressions in Linq

Subscribe

New Feed

Product Spotlight

Recently Updated Sources

Legal Note

The content of the postings is owned by the respective author. Silverlight Feeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on Silverlight Feeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us