LINQ. In the System.Linq namespace, we find many extensions to the C# language. These enhancements include support for query expressions, and extension methods.
With query expressions, we can search or sort a collection with just a few keywords, directly in the C# program. We can even group together elements in a certain way.
Query example. To begin, this example introduces a query expression—it starts with the keyword "from" which is a contextual keyword. Query expressions often end in "select."
Step 1 We use a query expression on the int array. We keep all elements greater than or equal to 10 in the result.
using System;
using System.Linq;
int[] values = { 1, 10, 100, 5 };
// Step 1: select all elements greater than or equal to 10.
var result = from v in values
where v >= 10
select v;
// Step 2: evaluate the query.
foreach (var value in result)
{
Console.WriteLine(value);
}10
100
Orderby. One of the most useful features of LINQ is orderby—this allows us to specify that a query sorts its results. Here we use the default int sort, which goes from low to high.
Tip We can specify the "ascending" keyword after the orderby clause, but it is the default, so this is not necessary.
using System;
using System.Linq;
int[] values = { 3, 10, -1, 30, -3 };
// Sort in ascending order, from low to high.
var result = from v in values
orderby v
select v;
foreach (var value in result)
{
Console.WriteLine(value);
}-3
-1
3
10
30
Descending. Sometimes we want a reverse-ordered sort—a descending instead of ascending sort. With LINQ, we can use orderby with the descending keyword after it.
using System;
using System.Linq;
string[] animals = { "cat", "turtle", "ant" };
// Sort strings reverse alphabetically, from last to first.
var result = from a in animals
orderby a descending
select a;
foreach (var value in result)
{
Console.WriteLine(value);
}turtle
cat
ant
Group. We can use query expressions to group together the results of the query. We need to end the query with a "group" clauses, which includes a "by" part.
Step 1 We create a list of 5 Tuples by calling List.Add 5 times. Each tuple has 2 items: an int, and a string.
Step 3 We evaluate the query and display the results. With a nested foreach loop, we display the complete results within each group.
using System;
using System.Collections.Generic;
using System.Linq;
// Step 1: create list of tuples.
var list = new List<Tuple<int, string>>();
list.Add(new Tuple<int, string>(5, "green"));
list.Add(new Tuple<int, string>(5, "blue"));
list.Add(new Tuple<int, string>(20, "orange"));
list.Add(new Tuple<int, string>(20, "yellow"));
list.Add(new Tuple<int, string>(20, "magenta"));
// Step 2: use query to group by first item in each tuple.
var result = from v in list
group v by v.Item1;
// Step 3: display results.
foreach (var value in result)
{
Console.WriteLine(value.Key);
foreach (var item in value)
{
Console.WriteLine(" " + item.Item2);
}
}5
green
blue
20
orange
yellow
magenta
Extension method. When we include the System.Linq namespace, we gain access to many extension methods that act upon IEnumerables. The Average() method is one such extension.
using System;
using System.Linq;
int[] numbers = { 2, 4, 6, 8 };
// Use Average extension method.
var average = numbers.Average();
Console.WriteLine(average);5
Chain extensions. It is possible to call an extension method right after another one—in this way, we can "chain" extension methods. Here we use Take, and then Average the result of Take.
using System;
using System.Linq;
int[] elements = { 5, 10, 15, 20, 25 };
// Average first 3 numbers.
var averageFirst3 = elements.Take(3).Average();
Console.WriteLine(averageFirst3);10
Any extension, lambda. The Any() method is an extension—we must include System.Linq to access it. It receives a lambda expression (a Predicate) that must return a bool value.
using System;
using System.Linq;
int[] values = { 10, -200, 1, 30, -1 };
// Use Any() to determine if a negative number exists.
var hasNegative = values.Any(x => x < 0);
Console.WriteLine(hasNegative);True
Query with extension. We can use an extension method directly upon a query expression—we need to surround the expression in parentheses. Here we Take() the first 2 results of an orderby query.
using System;
using System.Linq;
int[] numbers = { 5, 10, 1 };
// Use Take directly on a query.
var result = (from n in numbers
orderby n
select n).Take(2);
foreach (var value in result)
{
Console.WriteLine(value);
}1
5
FirstOrDefault. With this method, we get the first element in an IEnumerable, if one exists. If the collection if empty, we get the default value—for int, this is 0.
using System;
using System.Linq;
int[] elements = { 5, 10, 15, 20, 25 };
// Part 1: use FirstOrDefault when an element exists.
var first1 = elements.FirstOrDefault();
Console.WriteLine("FIRSTORDEFAULT: {0}", first1);
elements = new int[] {};
// Part 2: use FirstOrDefault on empty collection.
var first2 = elements.FirstOrDefault();
Console.WriteLine("FIRSTORDEFAULT: {0}", first2);FIRSTORDEFAULT: 5
FIRSTORDEFAULT: 0
ElementAtOrDefault. Similar to the FirstOrDefault method, ElementAtOrDefault allows us to safely get an element at any index. If we pass an out-of-range index, the default value is returned.
Also The ElementAt method is shown. This extension method will throw an extension if the index is out-of-range.
using System;
using System.Linq;
string[] sizes = { "small", "medium", "large" };
// Use ElementAtOrDefault with various indexes.
var element1 = sizes.ElementAtOrDefault(1);
Console.WriteLine("ELEMENTATORDEFAULT: {0}", element1);
var element100 = sizes.ElementAtOrDefault(100);
Console.WriteLine("ELEMENTATORDEFAULT: {0}", element100);
// Use ElementAt, which may cause an error.
var element2 = sizes.ElementAt(2);
Console.WriteLine("ELEMENTAT: {0}", element2);ELEMENTATORDEFAULT: medium
ELEMENTATORDEFAULT:
ELEMENTAT: large
Summary. LINQ is a powerful feature in the C# language, and its many extension methods can often simplify programs. And query expressions often help with sorting elements within a collection.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.