.NET 9 Features
Learn, Share and feel the difference
//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));
}
var guid = Guid.NewGuid(); // v4 UUID
var guidv7 = Guid.CreateVersion7(); // v7 UUID
var guidList = new List
{
Guid.CreateVersion7(TimeProvider.System.GetUtcNow()),
Guid.CreateVersion7(TimeProvider.System.GetUtcNow().AddMinutes(-10)),
Guid.CreateVersion7(TimeProvider.System.GetUtcNow().AddMinutes(10)),
Guid.CreateVersion7(TimeProvider.System.GetUtcNow().AddMinutes(-20))
};
//write the guids in whatever list contains.
foreach (var v7guid in guidList)
{
Console.WriteLine(v7guid.ToString());
}
Console.WriteLine("=====================");
//Order the guidlist and then write list.
//The result you can identify guids are ordered based on creation time.
var sortedList = guidList.OrderBy(x => x).ToList();
foreach (var v7guid in sortedList)
{
Console.WriteLine(v7guid.ToString());
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
var employees = new List {
new Employee(){ Id = 11, Name = "Ram" },
new Employee(){ Id = 12, Name = "Bheem" },
new Employee(){Id = 13, Name = "Lakshman"},
new Employee(){Id = 14, Name = "Hanu"},
new Employee(){Id = 15, Name = "Dev"},
new Employee(){Id = 16, Name = "Nandan"},
new Employee(){Id = 17, Name = "Krish"},
new Employee(){Id = 18, Name = "Hash"},
};
foreach ((int index, Employee emp) in employees.Index())
{
Console.WriteLine($"Index: {index}, Employee Name: {emp.Name}");
}