Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've spent way too many hours of my career writing the same pattern: create an empty list, loop through a collection, check an if statement, and add the matching item to that new list. It's tedious, it's boilerplate, and frankly, it clutters the logic of what we're actually trying to achieve. Let's look at a real scenario and see if we can find a cleaner way to handle data.

Imagine we're building a simple inventory manager for a game shop. I've got a list of products, and I only want to find the ones that are currently in stock and cost less than $50.

var products = new List<Product>
{
    new Product { Name = "Retro Console", Price = 89.99m, InStock = true },
    new Product { Name = "Controller", Price = 25.00m, InStock = true },
    new Product { Name = "Game Card A", Price = 15.00m, InStock = false },
    new Product { Name = "Game Card B", Price = 12.00m, InStock = true },
    new Product { Name = "Headset", Price = 45.00m, InStock = true }
};

// The "old school" way
var affordableInStock = new List<Product>();
foreach (var p in products)
{
    if (p.InStock && p.Price < 50)
    {
        affordableInStock.Add(p);
    }
}

Replacing the loop with a filter

That works, but it's noisy. I'm telling the computer how to do it (create list, loop, check, add) rather than what I want. This is where Language Integrated Query (LINQ) comes in. I'll try using the Where method. I've noticed it takes a lambda expression—essentially a mini-function—to define the criteria.

using System.Linq;

// ... 

var filtered = products.Where(p => p.InStock && p.Price < 50);

At first glance, this is beautiful. One line. But if I try to debug this and hover over filtered, I'll see it isn't actually a List<Product>. It's an IEnumerable<Product>. This is a crucial distinction. LINQ uses "deferred execution." The filtering hasn't actually happened yet; C# has just stored the instructions on how to filter the list when we finally decide to iterate over it.

If I need this to be a concrete list right now—maybe because I'm passing it to a method that requires a List—I have to force the execution. I'll add .ToList() to the end.

var filteredList = products.Where(p => p.InStock && p.Price < 50).ToList();

Narrowing the focus with projection

Now, let's say I don't actually need the whole Product object. I just want a list of the names of these affordable items to display in a UI dropdown. Right now, I'd have to loop through my filteredList again to extract the names. That feels inefficient.

I'll try the Select method. In LINQ terms, this is called "projection." It transforms each element into something else.

var names = products.Where(p => p.InStock && p.Price < 50)
                    .Select(p => p.Name)
                    .ToList();

I love this because I can chain these operations. The data flows through a pipeline: First, we filter out the expensive or out-of-stock items (Where), then we strip away everything but the name (Select), and finally, we solidify the result into a list (ToList).

Wait, what about Query Syntax?

If you look at older C# code or certain tutorials, you'll see a completely different style that looks almost like SQL. It's called Query Syntax. I'll try rewriting the same logic using this style to see if it's actually better.

var namesQuery = from p in products
                  where p.InStock && p.Price < 50
                  select p.Name;

Honestly? It's a matter of taste. Some people find this more readable for complex queries with multiple joins. However, in my experience, the method syntax (the .Where().Select() chain) is far more common in professional codebases and is generally more flexible when you start getting into more advanced LINQ operators. I'll stick with the method syntax for now, but it's good to recognize the query style so you aren't confused when you see it in a legacy project.




📋 Practical Task

Filtering and Projecting the Employee Directory

You are tasked with creating a report from a list of employees. You have a Employee class with the following properties: Name (string), Department (string), and YearsOfService (int).

Given the following list:

var employees = new List<Employee>
{
    new Employee { Name = "Alice", Department = "Engineering", YearsOfService = 5 },
    new Employee { Name = "Bob", Department = "Sales", YearsOfService = 2 },
    new Employee { Name = "Charlie", Department = "Engineering", YearsOfService = 10 },
    new Employee { Name = "Diana", Department = "HR", YearsOfService = 8 },
    new Employee { Name = "Eve", Department = "Engineering", YearsOfService = 3 }
};

Write a LINQ query using method syntax that does the following:

  • Filters the list to include only employees in the "Engineering" department.
  • Further filters those employees to include only those with more than 4 years of service.
  • Projects the result so you only have a list of their Name values.
  • Converts the final result into a List<string>.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.