Hooked on LINQ

Hooked on LINQ - Developers' Wiki
for .NET Language Integrated Query

Companion book for this site
LINQ to Objects Using C# 4.0:
Using and Extending LINQ to Objects and Parallel LINQ (PLINQ)
Quick Search

Advanced Search »
Edit

Chapter 2 - Introducing LINQ to Objects





Edit

Language Features

Edit

Listing 2-1 : This example demonstrates adding a GetSHA1Hash method to the String type as an example extension method

This example demonstrates adding a GetSHA1Hash method to the String type as an example extension method.

public void Listing_2_1_ExtensionMethods()
{
    // SHA1 Hashing a string. 
    // GetSHA1Hash is introduced via extension method
    string password = "ClearTextPassword";
    string hashedPassword = password.GetSHA1Hash();
 
    // write the results to the Console window
    Console.WriteLine("– SHA1 Hashing a string –");
    Console.WriteLine("Original: " + password);
    Console.WriteLine("Hashed: " + hashedPassword);
}
 
public static class MyStringExtensions
{
    // extension method added to the String type, 
    // with no additional arguments
    public static string GetSHA1Hash(
        this string text)
    {
        if (string.IsNullOrEmpty(text))
            return null;
        
        SHA1Managed sha1 = new SHA1Managed();
 
        byte[] bytes = sha1.ComputeHash(
            new UnicodeEncoding().GetBytes(text));
 
        return Convert.ToBase64String(bytes);
    }
 
    // extension method added to the String type,
    // single string argument: url.
    public static string CreateHyperlink(
        this string text, 
        string url)
    {
        return String.Format(
            "<a href='{0}'>{1}</a>", url, text);
    }
}
 

Console output (Execution time: 2ms): [Hide/Show]


Top



Edit

Listing 2 : Extension Methods

This sample demonstrates how to add Extension Methods to various types.

public void Listing_2_ExtensionMethods()
{
    // creating a hyperlink HTML snippet
    // CreateHyperlink introduced via extension method
    string name = "Hooked on LINQ";
    string link = name.CreateHyperlink(
        "http://www.hookedonlinq.com");
 
    Console.WriteLine("– String to hyperlink –");
    Console.WriteLine("Original: " + name);
    Console.WriteLine("Hyperlink text: " + link);
    Console.WriteLine();
}
 
public static class MyStringExtensions
{
    // extension method added to the String type, 
    // with no additional arguments
    public static string GetSHA1Hash(
        this string text)
    {
        if (string.IsNullOrEmpty(text))
            return null;
        
        SHA1Managed sha1 = new SHA1Managed();
 
        byte[] bytes = sha1.ComputeHash(
            new UnicodeEncoding().GetBytes(text));
 
        return Convert.ToBase64String(bytes);
    }
 
    // extension method added to the String type,
    // single string argument: url.
    public static string CreateHyperlink(
        this string text, 
        string url)
    {
        return String.Format(
            "<a href='{0}'>{1}</a>", url, text);
    }
}
 

Console output (Execution time: 0ms): [Hide/Show]


Top



Edit

Listing 2-2 : Object initializer syntax - before and after

This sample demonstrates the before and after syntax changes of Object Initializers.

public void Listing_2_2_ObjectInitializers()
{
    // old initialization syntax => multiple statements
    Contact contactOld = new Contact();
    contactOld.LastName = "Magennis";
    contactOld.DateOfBirth = new DateTime(1973, 12, 09);
 
    // new initialization syntax => single statement
    Contact contactNew = new Contact
    {
        LastName = "Magennis",
        DateOfBirth = new DateTime(1973, 12, 09)
    };
}
 
public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string State { get; set; }
 
    public static List<Contact> SampleData()
    {
        return new List<Contact> {
            new Contact {FirstName = "Barney",     LastName = "Gottshall",     DateOfBirth = new DateTime(1945,10,19), Phone = "885 983 8858", Email = "bgottshall@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Armando",    LastName = "Valdes",        DateOfBirth = new DateTime(1973,12,09), Phone = "848 553 8487", Email = "val1@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Adam",       LastName = "Gauwain",       DateOfBirth = new DateTime(1959,10,03), Phone = "115 999 1154", Email = "adamg@aspiring–technology.com", State = "AK" },
            new Contact {FirstName = "Jeffery",    LastName = "Deane",         DateOfBirth = new DateTime(1950,12,16), Phone = "677 602 6774", Email = "jeff.deane@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Collin",     LastName = "Zeeman",        DateOfBirth = new DateTime(1935,02,10), Phone = "603 303 6030", Email = "czeeman@aspiring–technology.com", State = "FL" },
            new Contact {FirstName = "Stewart",    LastName = "Kagel",         DateOfBirth = new DateTime(1950,02,20), Phone = "546 607 5462", Email = "kagels@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Chance",     LastName = "Lard",          DateOfBirth = new DateTime(1951,10,21), Phone = "278 918 2789", Email = "lard@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Blaine",     LastName = "Reifsteck",     DateOfBirth = new DateTime(1946,05,18), Phone = "715 920 7157", Email = "blaine@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Mack",       LastName = "Kamph",         DateOfBirth = new DateTime(1977,09,17), Phone = "364 202 3644", Email = "mack.kamph@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Ariel",      LastName = "Hazelgrove",    DateOfBirth = new DateTime(1922,05,23), Phone = "165 737 1656", Email = "arielh@aspiring–technology.com", State = "OR" }
        };
 
    }
}
 



Top



Edit

Listing 2-3 :Collection Initialization syntax - before and after

This sample demonstrates the before and after syntax changes of Collection Initializers.

public void Listing_2_3_CollectionInitializers()
{
    // old initialization syntax => multiple statements
    List<string> stringsOld = new List<string>();
    stringsOld.Add("string 1");
    stringsOld.Add("string 2");
 
    // new initialization syntax => single statement
    List<string> stringsNew = new List<string> {
        "string 1",
        "string 2" };
 
    // combining object and collection initialization
    // create a list of contacts and add two records.
    List<Contact> list = new List<Contact> {
        new Contact { 
            LastName = "Magennis",
            DateOfBirth = new DateTime(1973,12,09) 
        },
        new Contact {
            LastName = "Doherty",
            DateOfBirth = new DateTime(1978,1,05)
        }
    };
}
 
public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string State { get; set; }
 
    public static List<Contact> SampleData()
    {
        return new List<Contact> {
            new Contact {FirstName = "Barney",     LastName = "Gottshall",     DateOfBirth = new DateTime(1945,10,19), Phone = "885 983 8858", Email = "bgottshall@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Armando",    LastName = "Valdes",        DateOfBirth = new DateTime(1973,12,09), Phone = "848 553 8487", Email = "val1@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Adam",       LastName = "Gauwain",       DateOfBirth = new DateTime(1959,10,03), Phone = "115 999 1154", Email = "adamg@aspiring–technology.com", State = "AK" },
            new Contact {FirstName = "Jeffery",    LastName = "Deane",         DateOfBirth = new DateTime(1950,12,16), Phone = "677 602 6774", Email = "jeff.deane@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Collin",     LastName = "Zeeman",        DateOfBirth = new DateTime(1935,02,10), Phone = "603 303 6030", Email = "czeeman@aspiring–technology.com", State = "FL" },
            new Contact {FirstName = "Stewart",    LastName = "Kagel",         DateOfBirth = new DateTime(1950,02,20), Phone = "546 607 5462", Email = "kagels@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Chance",     LastName = "Lard",          DateOfBirth = new DateTime(1951,10,21), Phone = "278 918 2789", Email = "lard@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Blaine",     LastName = "Reifsteck",     DateOfBirth = new DateTime(1946,05,18), Phone = "715 920 7157", Email = "blaine@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Mack",       LastName = "Kamph",         DateOfBirth = new DateTime(1977,09,17), Phone = "364 202 3644", Email = "mack.kamph@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Ariel",      LastName = "Hazelgrove",    DateOfBirth = new DateTime(1922,05,23), Phone = "165 737 1656", Email = "arielh@aspiring–technology.com", State = "OR" }
        };
 
    }
}
 



Top



Edit

Listing 2-4 : Local variable declaration, implicitly typed examples

This sample demonstrates Implicitly typed local variables.

public void Listing_2_4_ImplicitlyTypedLocalVariables()
{
    // implicitly typed local variable declarations
    var anInt = 1;
    var aString = "Testing";
    var listContact = new List<Contact>();
    var intArray = new int[] { 0, 1, 2, 3, 4 };
 
    // the above are identical to the following declarations
    int anIntOld = 1;
    string aStringOld = "Testing";
    List<Contact> listContactOld = new List<Contact>();
    int[] intArrayOld = new int[] { 0, 1, 2, 3, 4 };
 
    // list is defined as type: List<Contact>,
    // it shows how object and collection 
    // initialization work with the var style init.
    var list = new List<Contact> {
        new Contact { 
            LastName = "Magennis",
            DateOfBirth = new DateTime(1973,12,09) 
        },
        new Contact {
            LastName = "Doherty",
            DateOfBirth = new DateTime(1978,1,05)
        }
    };
 
    /* The following declarations won't compile: 
    (courtesy of the C# 3.0 Language Specification)
     
    var x; // no initializer to infer type from               
    var z = null; // null does not have a type
    var u = 
      delegate { return 1; }; // anon. function has no type  
    var v = v++; // initializer cannot refer to itself        
    var y = {1, 2, 3}; // array initializer not permitted
    
    */
 
    // just to remove compiler warnings.
    anInt = anIntOld;
    aString = aStringOld;
}
 
public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string State { get; set; }
 
    public static List<Contact> SampleData()
    {
        return new List<Contact> {
            new Contact {FirstName = "Barney",     LastName = "Gottshall",     DateOfBirth = new DateTime(1945,10,19), Phone = "885 983 8858", Email = "bgottshall@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Armando",    LastName = "Valdes",        DateOfBirth = new DateTime(1973,12,09), Phone = "848 553 8487", Email = "val1@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Adam",       LastName = "Gauwain",       DateOfBirth = new DateTime(1959,10,03), Phone = "115 999 1154", Email = "adamg@aspiring–technology.com", State = "AK" },
            new Contact {FirstName = "Jeffery",    LastName = "Deane",         DateOfBirth = new DateTime(1950,12,16), Phone = "677 602 6774", Email = "jeff.deane@aspiring–technology.com", State = "CA" },
            new Contact {FirstName = "Collin",     LastName = "Zeeman",        DateOfBirth = new DateTime(1935,02,10), Phone = "603 303 6030", Email = "czeeman@aspiring–technology.com", State = "FL" },
            new Contact {FirstName = "Stewart",    LastName = "Kagel",         DateOfBirth = new DateTime(1950,02,20), Phone = "546 607 5462", Email = "kagels@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Chance",     LastName = "Lard",          DateOfBirth = new DateTime(1951,10,21), Phone = "278 918 2789", Email = "lard@aspiring–technology.com", State = "WA" },
            new Contact {FirstName = "Blaine",     LastName = "Reifsteck",     DateOfBirth = new DateTime(1946,05,18), Phone = "715 920 7157", Email = "blaine@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Mack",       LastName = "Kamph",         DateOfBirth = new DateTime(1977,09,17), Phone = "364 202 3644", Email = "mack.kamph@aspiring–technology.com", State = "TX" },
            new Contact {FirstName = "Ariel",      LastName = "Hazelgrove",    DateOfBirth = new DateTime(1922,05,23), Phone = "165 737 1656", Email = "arielh@aspiring–technology.com", State = "OR" }
        };
 
    }
}
 



Top



Edit

Listing 2-5 : Declaring and using Anonymous Types

This sample demonstrates Anonymous Types.

public void Listing_2_5_AnonymousTypes()
{
    // simple anonymous type declaration
    Console.WriteLine("– Simple Anonymous Type –");
    var item = new { Name = "Car", Price = 9989.00 };
 
    Console.WriteLine("Type: {0}, Name: {1}, Price: {2}",
        item.GetType().ToString(), item.Name, item.Price);
 
    // declaring and working with array of anonymous types
    Console.WriteLine();
    Console.WriteLine("– Iterating Anonymous Types Array –");
    var list = new[] {
        new { LastName = "Magennis",
              DateOfBirth = new DateTime(1973,12,09) 
        },
        new { LastName = "Doherty",
              DateOfBirth = new DateTime(1978,1,05)
        }
    };
 
    foreach (var x in list)
        Console.WriteLine("{0} ({1})",
            x.LastName, x.DateOfBirth);
 
    // compiler optomization – from the C# specification:
    // within the same program, two anonymous object
    // initializers that specify a sequence of properties of 
    // the same names and compile–time types in the same order
    // will produce instances of the same anonymous type. 
    var p1 = new { Name = "Lawnmower", Price = 495.00 };
    var p2 = new { Name = "Shovel", Price = 26.95 };
    p1 = p2; // valid: the same anonymous type
}
 

Console output (Execution time: 3ms): [Hide/Show]


Top



Edit

Listing 2-6 : Anonymous method (C# 2.0) and lambda expression (C# 3.0) examples

This sample demonstrates Lambda Expressions and Anonymous Types.

public void Listing_2_6_LambdaExpressions()
{
    // connecting code to a buttons click event
    //   anonymous method –
    Button button = new Button();
    button.Click += delegate(object sender, EventArgs args)
    {
        MessageBox.Show("Clicked");
    };
 
    //   lambda expression –
    button.Click += (object sender, EventArgs args) =>
        MessageBox.Show("Clicked");
 
    var data = Contact.SampleData().ToList();
 
    // passing code to a ForEach method on a List<T>
    //   anonymous method –
    data.ForEach(delegate(Contact c) 
        { c.LastName = c.LastName.ToUpper(); });
 
    // lambda expression –
    data.ForEach(c => c.LastName = c.LastName.ToUpper());
 
    data.ForEach( c => Console.WriteLine("{0}, {1}", 
        c.LastName, c.FirstName) );
 
    // passing code to an extension method
    // anonymous method –
    var q1 = data
             .Where(
                delegate(Contact c){return c.State == "WA";});
    
    // lambda expression –
    var q2 = data
             .Where(c => c.State == "WA");
}
 

Console output (Execution time: 7ms): [Hide/Show]


Top



Edit

Listing 2-7 : Query Expressions

This sample demonstrates Query Expressions and how the language enhancement meld into the LINQ story..

public void Listing_2_7_QueryExpressions()
{
    // note: Person.SampleData() returns a populated 
    // List<Person> sample data collection.
 
    // LINQ Query Expression Syntax
    var query1 = from c in Person.SampleData()
                 where c.State == "WA"
                 select new
                 {
                     Name = c.FirstName + " " + c.LastName,
                     State = c.State
                 };
 
    // LINQ Extension Method Syntax, identical to above
    var query2 = Person.SampleData()
                 .Where(c => c.State == "WA")
                 .Select(c => new
                 {
                     Name = c.FirstName + " " + c.LastName,
                     State = c.State
                 });
 
    foreach (var item in query1)
        Console.WriteLine("{0}, ({1})", item.Name, item.State);
}
 
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string State { get; set; }
 
    public static List<Person> SampleData()
    {
        // note: this sample data uses the Collection Initializer C#3.0 
        // language construct for simplicity.
        return new List<Person> {
            new Person { FirstName = "Troy",   LastName = "Magennis",  State = "WA" },
            new Person { FirstName = "Janet",  LastName = "Doherty",   State = "MA" },
            new Person { FirstName = "James",  LastName = "Wann",      State = "CA" },
            new Person { FirstName = "Tara",   LastName = "Wann",      State = "WA" }
        };
    }
}
 

Console output (Execution time: 7ms): [Hide/Show]


Top



Edit

LINQ to Objects Five Minute Overview

Edit

Listing 2-8 : Simple LINQ Query over an array of integers

This sample demonstrates a simple LINQ query over an integer array.

public void Listing_2_8_SimpleQueryExpression()
{
    int[] nums = new int[] { 0, 4, 2, 6, 3, 8, 3, 1 };
 
    var result = from n in nums
                 where n < 5
                 orderby n
                 select n;
 
    foreach (int i in result)
        Console.WriteLine(i);
}
 

Console output (Execution time: 24ms): [Hide/Show]


Top



Edit

Listing 2-9 : Simple LINQ that calculates the sum of all values in an integer array

This sample demonstrates a simple LINQ aggregation operator query that sums the values in an integer array.

public void Listing_2_9_SimpleAggregationQueryExpression()
{
    int[] nums = new int[] { 0, 4, 2, 6, 3, 8, 3, 1 };
    int result = nums.Sum();
    Console.WriteLine(result);
}
 

Console output (Execution time: 0ms): [Hide/Show]


Top



Edit

Listing 2-10 : Contacts who are less than 35 years of age

This sample demonstrates how to find all Contact less than 35 years of age, ordered from youngest to oldest.

public void Listing_2_10_ContactsLessThan35()
{
    List<Contact> contacts = Contact.SampleData();
 
    var q = from c in contacts
            where c.DateOfBirth.AddYears(35) > DateTime.Now
            orderby c.DateOfBirth descending
            select string.Format("{0} {1} b.{2}",
                      c.FirstName,
                      c.LastName,
                      c.DateOfBirth.ToString("dd–MMM–yyyy")
                    );
 
    foreach (string s in q)
        Console.WriteLine(s);
}
 

Console output (Execution time: 11ms): [Hide/Show]


Top



Edit

Listing 2-11 : Simple grouping based on a field value.

This sample demonstrates how to create sub-groups based on the value of an expression (all records matching that expression).

public void Listing_2_11_ContactGrouping()
{
    List<Contact> contacts = Contact.SampleData();
 
    var q = from c in contacts
            group c by c.State;
 
    foreach (var group in q)
    {
        Console.WriteLine("State: " + group.Key);
        foreach (Contact c in group)
            Console.WriteLine("  {0} {1}",
                c.FirstName,
                c.LastName);
    }
 
}
 

Console output (Execution time: 4ms): [Hide/Show]


Top



Edit

Listing 2-12 : Simple joining based on a shared value value.

This sample demonstrates how to join two in-memory collections based on a shared value.

public void Listing_2_12_JoiningData()
{
    List<Contact> contacts = Contact.SampleData();
    List<CallLog> callLog = CallLog.SampleData();
 
    var q = from call in callLog
            join contact in contacts on
                 call.Number equals contact.Phone
            select new  {
                contact.FirstName,
                contact.LastName,
                call.When,
                call.Duration
            };
 
    foreach (var c in q)
        Console.WriteLine(
            "{0} – {1} {2} ({3}min)",
            c.When.ToString("ddMMM HH:m"), c.FirstName,
            c.LastName, c.Duration);
}
 

Console output (Execution time: 14ms): [Hide/Show]


Top



Edit

Listing 2-13 : Summarizing the data from two collections.

Incoming call log summary - shows filtering, ordering, grouping, joining and selection using aggregate values

public void Listing_2_13_SummarizingDataFromMultipleCollections()
{
    List<Contact> contacts = Contact.SampleData();
    List<CallLog> callLog = CallLog.SampleData();
 
    var q = from call in callLog
            where call.Incoming == true
            group call by call.Number into g
            join contact in contacts on 
                 g.Key equals contact.Phone
            orderby contact.FirstName, contact.LastName
            select new  {
                contact.FirstName,
                contact.LastName,
                Count = g.Count(),
                Avg = g.Average(c => c.Duration),
                Total = g.Sum(c => c.Duration)
            };
 
    foreach (var call in q)
        Console.WriteLine(
            "{0} {1} – Calls:{2}, Time:{3}mins, Avg:{4}mins",
            call.FirstName, call.LastName,
            call.Count, call.Total, Math.Round(call.Avg, 2));
 
}
 

Console output (Execution time: 10ms): [Hide/Show]


Top



If you would like to comment on this page, click on the Discuss button located on the top-right of each page. Feel free to edit any mistakes or omissions you find. If you have an objection or find in-appropriate content then contact the administrator. This website is not affiliated with Microsoft®, all content and opinions are those of the specific author and some advice, solutions and article may contain unintentional errors - please use care. Other websites by this author: Focused Objective, Geek Speak Decoded.