BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

LINQ
.NET 3.5+

LINQ Element Operators

The fifteenth part of the LINQ to Objects tutorial examines the element standard query operators. These operators allow single items to be extracted from collections based upon their position in the sequence or upon a provided predicate.

Element Operators

The standard query operators that we have considered in this tutorial to date have worked with entire sequences of values. In this article we will consider the element operators. These are a group of extension methods that allow you to extract individual items from a list based upon their index number within the sequence or using a predicate, usually provided as a lambda expression.

Using Element Operators

The element operators that we will look at have different effects depending upon the contents of the collections that they operate against and any predicates provided to the method parameters. To show the various behaviours we will use three arrays, each containing strings, as the source data for the sample code. Although strings are a simple type they are useful for demonstration purposes. All of the operators can be used with sequences of any data type as long as the collection implements the IEnumerable<T> interface.

The sample data is as follows:

string[] items = new string[] {
    "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten" };
string[] single = new string[] { "One Item" };
string[] empty = new string[] { };

First

The first of the element operators is First. When used without arguments, this extension method simply returns the first item from a sequence.

var item = items.First(); // "Zero"

If there are no items present in the sequence, the First method fails and throws an InvalidOperationException.

var item = empty.First(); // InvalidOperationException

You can also use the First method with an argument. The argument accepts a Func delegate that defines a predicate. When used in this manner, the returned value is the first item in the list where the condition returns true. If the sequence is empty, or when there are no items that cause the predicate to return true, an exception will be thrown.

var item = items.First(i => i.Length == 5); // "Three"

FirstOrDefault

The FirstOrDefault standard query operator is similar to First. It returns the first item in a sequence or the first item that matches a given predicate. However, if no such item exists, FirstOrDefault does not throw an exception. Instead, the default value for the type that was expected is returned. In the case of reference types this is null. For value types, the value that would be generated by default(T) for the type is returned.

The following sample shows the result of reading the first item from a sequence:

var item = items.FirstOrDefault(); // "Zero"

Unlike First, no exception is thrown when reading from an empty array:

var item = empty.FirstOrDefault(); // null

A predicate can be provided to find the first item that matches the given criteria:

var item = items.FirstOrDefault(i => i.Length == 5); // "Three"

If no item matches the condition, the default value is returned:

var item = items.FirstOrDefault(i => i.Length == 2); // null

Last

The Last method is similar to First. However, instead of returning the first item in a sequence it returns the last item. You can see this by executing the following:

var item = items.Last(); // "Ten"

As with First, a predicate can be provided to find the last matching item:

var item = items.Last(i => i.Length == 5);  // "Eight"

LastOrDefault

LastOrDefault is the equivalent of FirstOrDefault for the Last method. When used without an argument, the last item in the sequence is returned or a default value is generated if the sequence is empty. When used with a predicate, the last item matching the predicate, or a default value, is the result.

var item = items.LastOrDefault();                   // "Ten"
item = empty.LastOrDefault();                       // null
item = items.LastOrDefault(i => i.Length == 5);     // "Eight"
item = items.LastOrDefault(i => i.Length == 2);     // null

Single

The next element operator that we will consider is Single. If you expect a collection to contain only one item, or if a prior query should have a single result, the Single method will return that element. We can see this using the following code:

var item = singleItem.Single(); // "One Item"

As with some other element operators, an exception is thrown when the source collection is invalid. In the case of Single, when the sequence is empty or has more than one item, the method fails.

var item = empty.Single(); // Exception

An overloaded version of the Single method can be used with a Func delegate parameter. This changes the behaviour so that the one item that matches the predicate is returned.

var item = items.Single(i => i.StartsWith("E")); // "Eight"

Again, an exception will be thrown if there are zero matches or if two or more items in the sequence cause the lambda expression to return true:

var item = items.Single(i => i.StartsWith("F")); // Exception
15 October 2010