BlackWaspTM
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
15 October 2010