.NET 9 Features
//Before .NET 9
public static void PrintNumbers( params int[] numbers)
{
Console.WriteLine("Numbers in Array: " + string.Join(", ", numbers));
}
public static void PrintNumbers(List numbers)
{
Console.WriteLine("Numbers in List: " + string.Join(", ", numbers));
}
// .NET 9
public static void PrintNumbersInNET9(params ReadOnlySpan numbers)
{
Console.WriteLine("Numbers in ReadOnlySpan: " + string.Join(", ", numbers.ToArray()));
}
public static void PrintNumbersInNET9(params IEnumerable numbers)
{
Console.WriteLine("Numbers in IEnumerable: " + string.Join(", ", numbers));
}
Call those methods just like below.
// Using params with a Array or List
var numbersList = new List { 6, 7, 8 };
ParamsCollection.PrintNumbers(numbersList.ToArray());
ParamsCollection.PrintNumbers(numbersList);
// Using params with ReadOnlySpan
ParamsCollection.PrintNumbersInNET9([6, 7, 8]);
// Using params with List
ParamsCollection.PrintNumbersInNET9(numbersList.Where(x => x > 6));
The aforesaid scenario where you have two method overloads: one accepting params IEnumerable<T>
and another taking params ReadOnlySpan<T>
. The method resolution works as follows:
params ReadOnlySpan<T>
overload is chosen.params ReadOnlySpan<T>
overload is also selected, since arrays can be implicitly converted to ReadOnlySpan<T>
.List<T>
is passed, the params IEnumerable<T>
overload is preferred, as List<T>
implements IEnumerable<T>
but does not have an implicit conversion to ReadOnlySpan<T>
..ToArray()
and .ToList()
inherently introduce additional resource overhead. However, the updated implementation now supports passing Span<>
and IEnumerable<>
, optimizing memory usage and enabling lazy execution. This enhancement improves efficiency while offering greater flexibility for performance-critical scenarios.
public int EmplSalary { get; set; }
, _empSalary)
and internal getter/setter methods (void set_EmplSalary(int empSalary)
and int get_EmplSalary()
). field
keyword, which allows direct access to the backing field without the need for manual definition.
private int _empSalary;
public int EmpSalary
{
get => _empSalary;
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException(nameof(value),
"Salary must be greater than 0");
_empSalary = value;
}
}
public int EmployeeSalary
{
get => field;
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException(nameof(value),
"Salary must be greater than 0");
field = value;
}
}
public async Task TaskWhenEachFeature()
{
// Before
var tasks1 = Enumerable.Range(1, 5)
.Select(async i =>
{
await Task.Delay(1000);
return $"Task is {i} done in earlier.";
})
.ToList();
while (tasks1.Count > 0)
{
var completedTask = await Task.WhenAny(tasks1);
tasks1.Remove(completedTask);
Console.WriteLine(await completedTask);
}
// .NET 9 USAGE OF Task.WhenEach feature
Console.WriteLine("==.NET9 - Task.WhenEach feature");
var tasks2 = Enumerable.Range(1, 5)
.Select(async i =>
{
await Task.Delay(2000);
return $"Task In .NET9 {i} done";
})
.ToList();
await foreach (var completedTask in Task.WhenEach(tasks2))
Console.WriteLine(await completedTask);
}
public static void SearchValuesFeature()
{
var message = "Explore new feature of SearchValues improvements in .NET9".AsSpan();
// .NET 8
var charSearch = SearchValues.Create(['.','N', 'E', 'T']);
Console.WriteLine(message.ContainsAny(charSearch));
// .NET 9
var wordSearch = SearchValues.Create([".NET9", "of"], StringComparison.OrdinalIgnoreCase);
Console.WriteLine(message.ContainsAny(wordSearch));
}