Skip to content

Commit 242e803

Browse files
committed
Add .NET9 post
1 parent 3818b07 commit 242e803

File tree

4 files changed

+127
-1
lines changed

4 files changed

+127
-1
lines changed

_posts/2022-06-27-NET6LinqMethods.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ To use these new methods and overloads, install on your machine the latest versi
202202

203203
Voilà! These are four new LINQ methods released in the .NET 6 updated. I really like the FirstOrDefault with a safe default. That help us to prevent one of the [common LINQ mistakes]({% post_url 2022-06-13-LinqMistakes %}): using the `XOrDefault` methods without null checking afterwards.
204204

205-
To learn about LINQ and other methods, check my [quick guide to LINQ]({% post_url 2021-01-18-LinqGuide %}), these [five common LINQ methods in Pictures]({% post_url 2022-05-16-LINQMethodsInPictures %}) and [how to use LINQ GroupBy method]({% post_url 2022-05-30-HowToUseLinqGroupBy %}). For more C# content, check [C# Definitive Guide]({% post_url 2018-11-17-TheC#DefinitiveGuide %}) for a list of subjects every intermediate C# developer should know.
205+
To learn about LINQ and other methods, check my [quick guide to LINQ]({% post_url 2021-01-18-LinqGuide %}), these [five common LINQ methods in Pictures]({% post_url 2022-05-16-LINQMethodsInPictures %}), [how to use LINQ GroupBy method]({% post_url 2022-05-30-HowToUseLinqGroupBy %}) and [two new LINQ methods in .NET 9]({% post_url 2024-04-15-NET9LinqMethods %}).
206206

207207
{%include linq_course.html %}
208208

_posts/2022-12-16-HelperMethodsOnCollections.md

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ foreach (var (index, movie) in movies.Enumerated())
9191
}
9292
```
9393

94+
[.NET 9 introduced the Index method]({% post_url 2024-04-15-NET9LinqMethods %}) that works like our `Enumerated()`. We don't need to roll our own method anymore in recent versions of .NET.
95+
9496
Voilà! These are some of my favorite extension methods to work with collections. Some of them are workarounds to [avoid the NullReferenceException]({% post_url 2023-02-20-WhatNullReferenceExceptionIs %}) when working with collections. What extension methods do you use often?
9597

9698
If you want to learn more about LINQ, read my [Quick Guide to LINQ]({% post_url 2021-01-18-LinqGuide %}).

_posts/2024-04-15-NET9LinqMethods.md

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
layout: post
3+
title: "Two new LINQ methods in .NET 9: CountBy and Index"
4+
tags: tutorial csharp
5+
cover: Cover.png
6+
cover-alt: "a vintage camera"
7+
---
8+
9+
LINQ doesn't get new features with each release of the .NET framework. It just simply works. This time, .NET 9 introduced two new LINQ methods: `CountBy()` and `Index()`. Let's take a look at them.
10+
11+
## 1. CountBy
12+
13+
**CountBy groups the elements of a collection by a key and counts the occurrences of each key. With CountBy, there's no need to first group the elements of a collection to count its occurrences.**
14+
15+
For example, let's count all movies in our catalog by release year, of course, using `CountBy()`,
16+
17+
```csharp
18+
var movies = new List<Movie>
19+
{
20+
new Movie("Titanic", 1997, 4.5f),
21+
new Movie("The Fifth Element", 1997, 4.6f),
22+
new Movie("Forrest Gump", 1994, 4.3f),
23+
new Movie("Terminator 2", 1991, 4.7f),
24+
new Movie("Armageddon", 1998, 3.35f),
25+
new Movie("Platoon", 1986, 4),
26+
new Movie("My Neighbor Totoro", 1988, 5),
27+
new Movie("Pulp Fiction", 1994, 4.3f),
28+
};
29+
30+
var countByReleaseYear = movies.CountBy(m => m.ReleaseYear);
31+
// ^^^^^^^
32+
foreach (var (year, count) in countByReleaseYear)
33+
{
34+
Console.WriteLine($"{year}: [{count}]");
35+
}
36+
37+
// Output
38+
// 1997: [2]
39+
// 1994: [2]
40+
// 1991: [1]
41+
// 1998: [1]
42+
// 1986: [1]
43+
// 1988: [1]
44+
45+
Console.ReadKey();
46+
47+
record Movie(string Name, int ReleaseYear, float Rating);
48+
```
49+
50+
`CountBy()` returns a collection of `KeyValuePair` with the key in the first position and the count in the second one.
51+
52+
By the way, if that Console application doesn't look like one, it's because we're using [three recent C# features]({% post_url 2021-09-13-TopNewCSharpFeatures %}): the Top-level statements, records, and global using statements.
53+
54+
Before .NET 9.0, we needed to use [GroupBy() with a second parameter]({% post_url 2022-05-30-HowToUseLinqGroupBy %}) to transform each group, like this,
55+
56+
```csharp
57+
var countByReleaseYear = movies.GroupBy(
58+
x => x.ReleaseYear,
59+
(releaseYear, movies) => new
60+
// ^^^^^
61+
{
62+
Year = releaseYear,
63+
Count = movies.Count()
64+
// ^^^^^
65+
});
66+
```
67+
68+
`CountBy()` has the same spirit of [DistinctBy, MinBy, MaxBy, and other LINQ methods from .NET 6.0]({% post_url 2022-06-27-NET6LinqMethods %}). With these methods, we apply an action direcly on a collection using a key selector. We don't need to filter or group a collection first to apply that action.
69+
70+
<figure>
71+
<img src="https://images.unsplash.com/photo-1440404653325-ab127d49abc1?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=400&ixid=MnwxfDB8MXxyYW5kb218MHx8fHx8fHx8MTcxMDk3NzY4Mw&ixlib=rb-4.0.3&q=80&w=600" alt="Cinematographer's room">
72+
73+
<figcaption>Photo by <a href="https://unsplash.com/@imnoom?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Noom Peerapong</a> on <a href="https://unsplash.com/photos/two-reels-2uwFEAGUm6E?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a></figcaption>
74+
</figure>
75+
76+
## 2. Index
77+
78+
**Index projects every element of a collection alongside its position in the collection.**
79+
80+
Let's "index" our catalog of movies,
81+
82+
```csharp
83+
var movies = new List<Movie>
84+
{
85+
new Movie("Titanic", 1998, 4.5f),
86+
new Movie("The Fifth Element", 1997, 4.6f),
87+
new Movie("Terminator 2", 1991, 4.7f),
88+
new Movie("Avatar", 2009, 5),
89+
new Movie("Platoon", 1986, 4),
90+
new Movie("My Neighbor Totoro", 1988, 5)
91+
};
92+
93+
foreach (var (index, movie) in movies.Index())
94+
// ^^^^^
95+
{
96+
Console.WriteLine($"{index}: [{movie.Name}]");
97+
}
98+
99+
// Output
100+
// 0: [Titanic]
101+
// 1: [The Fifth Element]
102+
// 2: [Terminator 2]
103+
// 3: [Avatar]
104+
// 4: [Platoon]
105+
// 5: [My Neighbor Totoro]
106+
107+
Console.ReadKey();
108+
109+
record Movie(string Name, int ReleaseYear, float Rating);
110+
```
111+
112+
Unlike `CountBy()`, `Index()` returns named tuples. It returns `IEnumerable<(int Index, TSource Item)>`.
113+
114+
Before, we had to use the `Select()` overload or roll our own extension method. In fact, this is one of the [helpful extension methods I use to work with collections]({% post_url 2022-12-16-HelperMethodsOnCollections %}). But I call it `Enumerated()`.
115+
116+
If we take a look at the [Index source code on GitHub](https://github.com/dotnet/runtime/blob/main/src/libraries/System.Linq/src/System/Linq/Index.cs), it's a `foreach` loop with a counter in its body. Nothing fancy!
117+
118+
Voilà! Those are two new LINQ methods in .NET 9.0: `CountBy()` and `Index()`. It seems the .NET team is bringing to the standard library the methods we needed to roll ourselves before.
119+
120+
To learn about LINQ and other methods, check my [quick guide to LINQ]({% post_url 2021-01-18-LinqGuide %}), [five common LINQ mistakes and how to fix them]({% post_url 2022-06-13-LinqMistakes %}), and [peeking into LINQ DistinctBy source code]({% post_url 2022-07-11-LinqDistinctBySourceCode %}).
121+
122+
{%include linq_course.html %}
123+
124+
_Happy coding!_
Loading

0 commit comments

Comments
 (0)