Menu

Tuesday, 4 February 2025

 

.NET 9 Features

  1. Task.WhenEach in .NET 9
  2. CountBy LINQ in .NET 9
  3. AggregateBy LINQ in .NET 9
  4. Index LINQ in .NET 9
  5. UUID v7 in .NET9
  6. SearchValues improvements in .NET9
  7. Semi Auto Properties in .NET9
  8. Params Collection in .NET9

Params Collections in .NET9

 

About


The series of features exploring in .NET 9 posts, This post, we are focusing on "Params Collections" feature in .NET9. Please refer the following links for other .NET 9 features discussed in my earlier posts.

Introduction


Params collection is one of the feature in C#13. This params parameter can be of any types supported for collection parameters.
This enhanced feature helps to write code in cleaner way and it also improves in performance point of view as well.
Lets explore and understand about this with sample code by comparing before .NET9 and now.

Before .NET 9

 //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

 // .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:

  • When passing a sequence of values directly, the params ReadOnlySpan<T> overload is chosen.
  • If an array is provided as an argument, the params ReadOnlySpan<T> overload is also selected, since arrays can be implicitly converted to ReadOnlySpan<T>.
  • However, when a 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>.

Code Screenshots








Summary


Params collection feature provides these following benefits.
Cleaner code: It reduces the number of calls to .ToArray() and .ToList()
Performance: Methods like .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.

Thanks for your reading and as always share your feedback on this.


Friday, 17 January 2025

Semi Auto Properties in .NET9

 

About


The series of features exploring in .NET 9 posts, This post, we are focusing on "Semi Auto Properties" feature in .NET9. Please refer the following links for other .NET 9 features discussed in my earlier posts.

Introduction


Semi Auto Properties is available in Preview feature of C#13. This feature really helps Enhanced readability and reduced boilerplate code while declaring properties in class files.

Lets understand further by exploring more following information.

Usually, In C#, We declare an auto-implemented property like 
public int EmplSalary { get; set; }

The compiler automatically generates a backing field like (Ex: _empSalary) and internal getter/setter methods (void set_EmplSalary(int empSalary) and int get_EmplSalary()). 

However, In our real-time project cases, we need to set some custom logic such as validation, default values, computations, or lazy loading in the property’s getter or setter, we typically need to manually define the backing field. 
With C# 13 preview, this process is simplified by the introduction of the field keyword, which allows direct access to the backing field without the need for manual definition.

Edit the project file by adding <LangVersion>preview</LangVersion>. So, It supports field
property in project usage.


The following code gives more illustrative idea about usage.

Before .NET 9


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;
    }
}

In .NET 9


public int EmployeeSalary
{
    get => field;
    set
    {
        if (value <= 0)
            throw new ArgumentOutOfRangeException(nameof(value),
                "Salary must be greater than 0");
        field = value;
    }
}


Code Screenshot




Thanks for your reading and please share your feedback on comments.

Monday, 6 January 2025

Task.WhenEach in .NET9

 About


The series of features exploring in .NET 9 posts, This post, we are focusing on "Task.WhenEach" feature in .NET9. Please refer the following links for other .NET 9 features discussed in my earlier posts.

Introduction


Task.WhenEach is introduced in C#13 of .NET9. This is really helpful when we have list of tasks that completes in different time intervals and then we want to start other task as soon as it completes the current one. 

The below code example illustrates the usage of this feature by comparing/understand the earlier version with current version as well.


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);
}

Screenshots




Output




Wednesday, 1 January 2025

SearchValues Improvements in .NET9

 About


The series of features exploring in .NET 9 posts, This post, we are focusing on "SearchValues" improvements did in .NET9. Please refer the following links for other .NET 9 features discussed in my earlier posts.

SearchValues was introduced in .NET8 to perform searching more efficiently compared to earlier method of using ICollection.Contains method. However, in .NET8, Its limited to set of characters or bytes.
So, .NET9 its upgraded to support string as well instead of only character.

Lets explore the usage of  "SearchValues" usage in both .NET8 and .NET9 versions.

The below code example shows the usage of this feature in both .NET versions.
We can see that, .NET9 search supports string comparison type as well.


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));
}


Screenshots




Summary


This feature is defiantly used option in our day to day projects/development where we used to do search operations,  data input filter scenarios, spam detection checks and many more.

Thanks for your reading!!

Wednesday, 18 December 2024

UUID v7 in .NET 9

 

About


.NET 9 comes up with so many excited features as discussed in earlier posts. This post, we are focusing on UUID v7 feature.
Please refer the following links for other .NET 9 LINQ features

The earlier versions of .NET, we've used Guid.NewGuid() (version 4) method generate UUIDs. It simply generates unique identifier which being used in our projects.

The present .NET 9 version supports UUID v7 format of code like Guid.CreateVersion7(). This generated UUID incorporated timestamp already in it. So, This is really very helpful when we stored this UUID in database level to Sort it  based on creation time.

The structure of UUID format is as follows.

 48-bit timestamp || 12-bit random ||    62-bit random

48-bit timestamp: It represents the number of milliseconds since Unix epoch. so, It provides info about creation time.
12-bit random: It adds randomness to ensure uniqueness in within same millisecond.
62-bit random: It also ensures overall uniqueness by offering randomness of entropy.

Code Examples

Before .NET 9

var guid = Guid.NewGuid(); // v4 UUID

.NET 9

var guidv7 = Guid.CreateVersion7(); // v7 UUID
var guidv7 = Guid.CreateVersion7(); // v7 UUID
This by default inherits UtcNow timeformat.

Lets explore about Sort feature by creating multiple UUIDs custom way.

//Just added the guid by adding different time provider by add/subtract minutes to current Utc time.

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());
}

Screenshots









Summary


We have explored UUID v7 feature in .NET 9and its advantages of inbuilt timestamp which can be really helpful to order created UUIDs in database level. So, lets start use in our project and get benefitted.

Stay tuned for more articles. Thanks for reading!!



Monday, 16 December 2024

.NET 9 Index in LINQ

 

About


Index is one of feature introduced in .NET LINQ. By using this method, we can easily extract implicit index of IEnumerable.

The other .NET 9 LINQ features are as follows.

The Index method returns index and index of an item in following format.

Format: IEnumerable<(int Index, TSource Item)>

Scenario


Lets consider to display employee name in list and their respective order.

Employee class


public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}


Setup Employee List with Sample Data

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}");
  }
  
Screenshots

The following code and output screenshots gives easy understanding and for your implementation.

Code



Output



Summary



This post explored about Index feature in LINQ introduced in .NET9.
Thanks for reading this and stay tuned for more articles.