My Favorite C# Features Part 2: LINQ
Tags: dotnet, csharp, programming
Published: 2021-03-10 15:04:16


---
title: My Favorite C# Features Part 2:  LINQ
published: true
description: With C#, we can work with collections quickly with the Language Integrated Natural Query tools in .NET  With C#, we have flexible options to write queries and work with our data quickly and easily.
tags: dotnet, csharp, programming
series: My Favorite C# Features
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ggdngcfeqd8cp13ejda.PNG
---

Working with collections in any programming language always ends up with some sort of loop structure and ugly code to find an object, work on several objects, and exit the loop.  This is why I really enjoy using LINQ with C# -- all of this looping and aggregation code is hidden from me by the compiler and I can focus on writing the code that I actually need to get and work with data in a collection.  In this post, I'll review some of my favorite LINQ features that make me more productive in working with collections of data.

Throughout the samples below, we'll work with this collection of Hat objects.  It's a real collection, and yes I do have these hats IRL.  You can see a large selection of my hat collection at [https://hats.csharpfritz.com](https://hats.csharpfritz.com)

```csharp
public class Hat {

  // A name I've assigned to the hat
  public string Name { get; set; }

  // The year I acquired the hat
  public int Year { get; set; }

  // Theme of the hat: Sports, Movies, Tech, etc
  public string Theme { get; set; }
}

public static class HatCollection {
  public static readonly Hat[] Items = new Hat[] {
    new Hat { Name="Camp Crystal Lake", Year=2020, Theme="Movies" },
    new Hat { Name="Marauder's Map", Year=2020, Theme="Movies" },
    new Hat { Name="Super C#", Year=2018, Theme="Tech" },
    new Hat { Name="Dunder Mifflin", Year=2018, Theme="TV" },
    new Hat { Name="Space X", Year=2019, Theme="Tech" },
    new Hat { Name="Phillies 2008 World Series", Year=2008, Theme="Sports" },
    new Hat { Name="The Flash", Year=2021, Theme="TV" }
  };
}
```

![Fritz's The Flash hat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jnwkgh7p5bph0ssd9cqf.jpg)
<figcaption>Fritz's The Flash hat</figcaption>

##  Where - Find Some Data and Return It

What good is a collection of data if you can't search through it quickly with just a 1 line command?  The `Where` method can be used to quickly find the subset of items that meet your condition.  

Given the collection of hats, we could return just those hats that were acquired in 2020 with this command:

```csharp
var twentyTwentyHats = HatCollection.Items.Where(h => h.Year==2020);

// Returns "Camp Crystal Lake" and "Marauder's Map" hat objects
```

The contents of the `Where` method are called a lambda expression.  You define a lambda with a variable that will capture one of the items in the collection, add a 'fat arrow' and then the operation you want to process on that item.  In the case of a `Where` method, we are testing for a condition and returning a true or false boolean value to indicate if the item should be returned.  

In this case, we are testing if the `Year` property of the `Hat` is 2020.

## Are ANY of these Hats from before 2010?

The `Any` method is a simple check to return a true or false boolean value indicating if a condition is met.  If we want to search the collection for hats that are from before 2010, we could use this expression:

```csharp
var olderThanTwentyTen = HatCollection.Items.Any(h => h.Year < 2010);

// Returns true due to the presence of the 2008 Phillies hat
```

The `Any` method can operate quickly as it will stop looping through the collection as soon as the condition is met.

## Count those hats

Aggregate methods are available that allow you to count, sum, min, max, and average values inside the collection.  In addition to simply counting all of the items in the collection, we can provide a test method to count only those items that pass that test.

```csharp
var totalHats = HatCollection.Items.Count();

// This returns 7.. but honestly, 
// Fritz's hat collection is more than 100

var techHatsCount = HatCollection.Items.Count(h => h.Theme == "Tech");

// This will return 2 for "Super C#" and "Space X"
```

## Sorting done simply

Sorting is one of those computer science gotcha questions that ALWAYS comes up in an interview and nobody likes it.  When it comes to sorting collections in memory, I just let the experts who built .NET do it for me by using the `OrderBy` and `OrderByDescending` methods.  Simply provide a selector method that returns the property or value to order by and LINQ will return to you a collection of your objects in the order desired:

```csharp

var newestHatsFirst = HatCollection.Items.OrderByDescending(h => h.Year);

var orderByTheme = HatCollection.Items.OrderBy(h => h.Theme);
```

Did you know, you can chain these sort method together, or even connect them with a `Where` method to create a more interesting query?

```csharp
var techHatsNewestFirst = HatCollection.Items
    .Where(h => h.Theme == "Tech")
    .OrderByDescending(h => h.Year);

// This returns the "Space X", "Super C#" hat objects
```

## Project your output with Select

Just like in SQL, there is a `Select` method that can be used with LINQ to transform our collection from one object to another.  Perhaps we just want an array of the hat names... easy:

```csharp
var hatNames = HatCollection.Items.Select(h => h.Name);
```

You can use select to convert to another type, an anonymous type, or tuples.  Use `Select` to give you the shape and format of the data you need.

## Group By FTW!

It's nice to be able to sort and filter your data, but the real power comes in when you summarize a collection.  Let's use the `GroupBy` feature to summarize the number of hats in the collection by theme:

```csharp
var totalByTheme = HatCollection.Items
    .GroupBy(h => h.Theme)
    .Select(g => new {Theme=g.Key, Count=g.Count() });

foreach (var item in totalByTheme)
{
  Console.WriteLine($"Theme: {item.Theme}, Count: {item.Count}");
}

/* 
Outputs:

Theme: Movies, Count: 2
Theme: Tech, Count: 2
Theme: TV, Count: 2
Theme: Sports, Count: 1

*/
```

This `GroupBy` delivers a collection of grouped objects with a `Key` property that contains the value grouped by, in this case the `Theme` property.  We can then chain the `Select` method to project these groupings into a summary collection with the themes and the count of hats that belong to each theme.

## Summary

This is just the beginnings of the cool things you can do with LINQ. Put together with an object-relational mapper tool like Entity Framework and you have a very cool way to query your database.

Did you know, I host a weekly live stream on the [Visual Studio Twitch channel](https://twitch.tv/visualstudio) teaching the basics of C#?  Tune in on Mondays at 9a ET / 1400 UTC for two hours of learning in a beginner-friendly Q+A format with demos and sample code you can download.  I recently had an episode about LINQ that you can find on YouTube:

{% youtube knc4AVqHEr0 %}

Looking to get started learning C#? Checkout our [free on-demand courses on Microsoft Learn!](https://docs.microsoft.com/users/dotnet/collections/yz26f8y64n7k07?WT.mc_id=friends-0000-jefritz)