“Ordefault” value for default methods
The Enumerable.FirstOrDefault to a method returns a sequence's first element, or a default value if there are no items in the sequence. You can also override the default value for the SingleOrDefault and LastOrDefault methods.
List list1 = new() { 1, 2, 3 };
int item1 = list1.FirstOrDefault(i => i == 4, -1);
Console.WriteLine(item1); // -1
List list2 = new() { "Item1" };
string item2 = list2.SingleOrDefault(i => i == "Item2", "Not found");
Console.WriteLine(item2); // Not found
A new Chunk method
With the launch of the new Enumerable.chunk extension method in .NET Core 6, you are no longer required to implement the requirement to divide elements of the sequence into chunks.
IEnumerable numbers = Enumerable.Range(1, 505);
IEnumerable chunks = numbers.Chunk(100);
foreach (int[] chunk in chunks)
{
Console.WriteLine($"{chunk.First()}...{chunk.Last()}");
}
// Output:
// 1...100
// 101...200
// 201...300
// 301...400
// 401...500
// 501...505
New *By methods
Another crucial feature that gets added in .NET Core 6 is the new Enumerable.By* methods. It makes use of a 'key selector' and compares elements for further process.
Take a look at the new methods listed below.
- MaxBy
- MinBy
- DistinctBy
- IntersectBy
- ExceptBy
- UnionBy
List products = new()
{
new() { Name = "Product1", Price = 100 },
new() { Name = "Product2", Price = 5 },
new() { Name = "Product3", Price = 50 },
};
Product theCheapestProduct = products.MinBy(x => x.Price);
Product theMostExpensiveProduct = products.MaxBy(x => x.Price);
Console.WriteLine(theCheapestProduct);
// Output: Product { Name = Product2, Price = 5 }
Console.WriteLine(theMostExpensiveProduct);
// Output: Product { Name = Product1, Price = 100 }
record Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
Three-way Zip method
The three-way zip method (Enumerable.Zip extension method) produces the tuple with the element from the two given sequences. Now, with .NET 6 developers can combine tuples from three sequences and send them to the extension method.
int[] numbers = { 1, 2, 3, 4, };
string[] months = { "Jan", "Feb", "Mar" };
string[] seasons = { "Winter", "Winter", "Spring" };
var test = numbers.Zip(months).Zip(seasons);
foreach ((int, string, string) zipped in numbers.Zip(months, seasons))
{
Console.WriteLine($"{zipped.Item1} {zipped.Item2} {zipped.Item3}");
}
// Output:
// 1 Jan Winter
// 2 Feb Winter
// 3 Mar Spring
Index support in the ElementAt the method
The new unary to the prefix "hat" operator () is supported by the C# compiler thanks to the introduction of the Index struct in .NET Core 3.0. Now, in .NET 6, Enumerable.ElementAt method would be used to index “from the end” of the collection.
IEnumerable numbers = new int[] { 1, 2, 3, 4, 5 };
int last = numbers.ElementAt(^0);
Console.WriteLine(last); // 5IEnumerable numbers = new int[] { 1, 2, 3, 4, 5 };
int last = numbers.ElementAt(^0);
Console.WriteLine(last); // 5
The Range support in the “Take method”
In .NET Core 3.0, Range support for the struct was added. The function is used by the C# compiler to support the range operator "..". To support the range, .NET 6 makes use of a “Range struct” while code implementation.
IEnumerable numbers = new int[] { 1, 2, 3, 4, 5 };
IEnumerable taken1 = numbers.Take(2..4);
foreach (int I in taken1)
Console.WriteLine(i);
// Output:
// 3
// 4
IEnumerable taken2 = numbers.Take(..3);
foreach (int i in taken2)
Console.WriteLine(i);
// Output:
// 1
// 2
// 3
IEnumerable taken3 = numbers.Take(3..);
foreach (int i in taken3)
Console.WriteLine(i);
// Output:
// 4
// 5
The .NET 6 Avoiding Enumeration with TryGetNonEnumeratedCount
The .NET 6 introduces a new Enumerable.TryGetNonEnumerated to the method. It tries to determine the number of elements in the sequence without forcing an enumeration. This method can be used with IQueryable while calling Enumerable.Count that you don't want to evaluate the entire query.
IEnumerable numbers = GetNumbers();
TryGetNonEnumeratedCount(numbers);
// Output: Could not get a count of numbers without enumerating the sequence
IEnumerable enumeratedNumbers = numbers.ToList();
var test = enumeratedNumbers.ElementAt(-1);
TryGetNonEnumeratedCount(enumeratedNumbers);
// Output: Count: 5
void TryGetNonEnumeratedCount(IEnumerable numbers)
{
if (numbers.TryGetNonEnumeratedCount(out int count))
Console.WriteLine($"Count: {count}");
else
Console.WriteLine("Could not get a count of numbers without enumerating the sequence");
}
IEnumerable GetNumbers()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
yield return 5;
}