How LINQ works with in memory collections in C#

Web developer uses in this case the simplest form of LINQ – LINQ to Objects.  Let for example Web developer has some sort of data class, like the Clients class shown next:

 

public class Client

{

public int ClientID { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public string TitleOfCourtesy { get; set; }

public ClientID(int employeeID, string firstName, string lastName, string titleOfCourtesy)

{

ClientID = employeeID;

FirstName = firstName;

LastName = lastName;

TitleOfCourtesy = titleOfCourtesy;

}

}

 

Web developer can easily create collection that consists of Client objects, like the strongly typed List shown:

// Create the collection.

List<Client> clients = new List<Client>();

// Fill the collection.

clients.Add(new Client(100, “Brian”, “Shapp”, “Mr.”));

clients.Add(new Client(200, “Emilie”, “Heman”, “Ms.”));

clients.Add(new Client(300, “Robertt”, “Elliott”, “Dr.”));

 

The traditional approach to get a list of all clients who have a last name that starts with the letter D is to use code to loop through the full collection of clients and add each matching client to a second collection:

 

// Create the collection.

List<Client> clients = new List<Client>();

// Find the matching clients.

List<Client> matches = new List<Client>();

foreach (Client client in clients)

{

if (client.LastName.StartsWith(“D”))

{

matches.Add(client);

}

}

// Display the collection of the matches in a web page

gridClients.DataSource = matches;

gridClients.DataBind();

Web developer can use LINQ to Objects to replace iterative logic ( foreach block ) with a  declarative expression. The following example shows how Web developer can rewrite the earlier example, replacing the foreach block with a LINQ expression that queries the collection:

 

// Create the source collection.

List<Client> clients = new List<Client>();

// (Code for filling the collection omitted to save space.)

var matches = from client in clients

where client.LastName.StartsWith(“D”)

select client;

// Display the collection of the matches in a web page

gridClients.DataSource = matches;

gridClients.DataBind();

The new things here are:

  • The LINQ expression uses a set of new keywords, including from, in, where, and select. Web developer shapes his/her query using these keywords.
  • LINQ expressions return an usual type of object, called an iterator object. (In the example, the iterator object is named matches.)  Although the iterator object looks like an ordinary collection, it doesn’t actually hold any information. Instead, it has the ability to fetch the data when it is necessary. Wen Web developer examines the contents of an iterator object with a foreach block or when he/she binds it to a control, LINQ evaluates his/her expression and quickly grabs the information is needed. This is called deferred execution.
  • In the example the iterator object (named matches) is defined with the var keyword This is a shortcut that tells the C# compiler to use the correct data type, without forcing Web developer to specify it. Technically, the iterator object could be one of several different types of objects depending on the clauses used in in the LINQ expression. All of these objects implement the strongly typed version of the IEnumerable interface and Web developer can replace the var with IEnumerable<Client>, because the collection holds Client objects.