In this tutorial, you will learn how to use the ForEach method on Lists and other LINQ collections. This allows you to compactly write, on a single line of code, that which otherwise would take at least four lines.
Initial Setup
In the previous project, we started by creating a custom Book class designed to hold the title, author, and publication date of books. Then, we initialized a List
using System;
using System.Linq;
using System.Collections.Generic;
namespace IntroducingLINQ
{
class Program
{
static void Main(string[] args)
{
List<Book> bookList = new List<Book>()
{
new Book("Les Miserables", "Victor Hugo", 1862),
new Book("L'Etranger", "Albert Camus", 1942),
new Book("Le Tour du monde en quatre-vingts jours", "Jules Verne", 1869),
new Book("Madame Bovary", "Gustave Flaubert", 1857),
new Book("Le Comte de Monte-Cristo", "Alexandre Dumas", 1844),
new Book("Vingt mille lieues sous les mers", "Jules Verne", 1872),
new Book("Les Trois Mousquetaires", "Alexandre Dumas", 1844),
new Book("Candide", "Voltaire", 1759),
new Book("Notre-Dame de Paris", "Victor Hugo", 1831),
new Book("Voyage au centre de la Terre", "Jules Verne", 1864)
};
var subList = bookList.Where(p => p.Author == "Jules Verne" || p.Author == "Victor Hugo")
.OrderBy(p => p.Author)
.ThenBy(p => p.PubDate);
Console.WriteLine($"{subList.Count()} books match your search criteria:");
foreach (Book book in subList)
{
Console.WriteLine($" {book.Author} - {book.Title} ({book.PubDate})");
}
Console.ReadLine();
}
}
class Book
{
public string Title { get; set; }
public string Author { get; set; }
public int PubDate { get; set; }
public Book(string title, string author, int pubDate)
{
Title = title;
Author = author;
PubDate = pubDate;
}
}
}
IEnumerable and ToList()
When we used the var
keyword on Line 25, the compiler returned an IOrderedEnumerable type. This is an efficient data type when performing order operations on a set of data. For example, if the collection will be iterated over or re-ordered multiple times, there is no need to modify the original source list. In most scenarios, it is recommended to keep the returned data type.
However, there are certain operations that can be performed on lists, but which cannot be performed on an IEnumerable data types. For the sake of this tutorial, we will be performing one such operation. Fortunately, there is a way to convert an IOrderedEnumerable or IEnumerable to a List using the ToList()
method.
You will need to modify Lines 25-27. First, explicitly define the data type as a Book<List>
. Then, chain the .ToList()
method onto the end of the operation. This will convert the IEnumerable type to a List
List<Book> subList = bookList.Where(p => p.Author == "Jules Verne" || p.Author == "Victor Hugo")
.OrderBy(p => p.Author)
.ThenBy(p => p.PubDate)
.ToList();
LINQ Collections and ForEach
Now, we can replace the foreach
statement from Lines 31-34 of the initial setup code.
subList.ForEach(p => Console.WriteLine($" {p.Author} - {p.Title} ({p.PubDate})"));
This line says that for each item in the list, write some information corresponding to that item to the console. This example is simple, and doesn't have anything to do with operating on the actual data in the list. But, a collection's ForEach()
method can also be invoked to perform a number of other useful operations.
For example, suppose we decide to add a new property to the Book class - a book's Sales Price.
public double SalePrice { get; set; }
Instead of setting the value of SalePrice at the time of instantiation, we could use the collection's ForEach()
method to assign all the books an initial price.
bookList.ForEach(p => p.SalePrice = 14.99);
Now, suppose your bookstore was having a special 2 euro off sale for all Jules Verne books. Before you learned about LINQ, you might have used the following code.
foreach (Book book in bookList)
{
if (book.Author == " Jules Verne")
{
book.SalePrice -= 2;
}
}
With LINQ, however, all these lines of code can be replaced with a single line by chaining together a ForEach()
looping statement with a Where()
filtering method.
bookList.Where(p => p.Author == "Jules Verne").ToList().ForEach(p => p.SalePrice -= 2)
Your final project code may look similar to the following:
using System;
using System.Linq;
using System.Collections.Generic;
namespace IntroducingLINQ
{
class Program
{
static void Main(string[] args)
{
List<Book> bookList = new List<Book>()
{
new Book("Les Miserables", "Victor Hugo", 1862),
new Book("L'Etranger", "Albert Camus", 1942),
new Book("Le Tour du monde en quatre-vingts jours", "Jules Verne", 1869),
new Book("Madame Bovary", "Gustave Flaubert", 1857),
new Book("Le Comte de Monte-Cristo", "Alexandre Dumas", 1844),
new Book("Vingt mille lieues sous les mers", "Jules Verne", 1872),
new Book("Les Trois Mousquetaires", "Alexandre Dumas", 1844),
new Book("Candide", "Voltaire", 1759),
new Book("Notre-Dame de Paris", "Victor Hugo", 1831),
new Book("Voyage au centre de la Terre", "Jules Verne", 1864)
};
bookList.ForEach(p => p.SalePrice = 14.99);
bookList.Where(p => p.Author == "Jules Verne").ToList().ForEach(p => p.SalePrice -= 2);
List<Book> orderedList = bookList.OrderBy(p => p.Author).ThenBy(p => p.PubDate).ToList();
orderedList.ForEach(p => Console.WriteLine($"{p.SalePrice:C} - {p.Author} - {p.Title} ({p.PubDate})"));
Console.ReadLine();
}
}
class Book
{
public string Title { get; set; }
public string Author { get; set; }
public int PubDate { get; set; }
public double SalePrice { get; set; }
public Book(string title, string author, int pubDate)
{
Title = title;
Author = author;
PubDate = pubDate;
//SalePrice = 14.99;
}
}
}
The Bottom Line
In this tutorial, you learned how to convert a generic IEnumerable type, IEnumerableForEach()
method with C# Lists. This allows you to compactly write in one line that which would otherwise take multiple lines of code. There is a lot more to discover with LINQ, so if you have questions, let me know in the comments!
Don't stop learning!
There is so much to discover about C#. That's why I am making my favorite tips and tricks available for free. Enter your email address below to become a better .NET developer.
Did you know?
Our beautiful, multi-column C# reference guides contain more than 150 tips and examples to make it even easier to write better code.
Get your cheat sheets