DEV Community

Cover image for 7 overlooked .Net features
Sergey Shamov
Sergey Shamov

Posted on

7 overlooked .Net features

.Net is constantly evolving, a new version comes out every year, and it's easy to lose track of some of the useful changes.
I compiled a list of 7 (mostly) recent features that I from my code reviews I think get overlooked by devs (or devs' AI tools).

1. Extension Members (C# 14)

In addition to extension methods, we can now add extension properties and static methods to a type.
Properties are mostly just for readability, and static extension methods are useful for writing factory methods instead of creating a separate factory class.

So instead of

public static class CustomerExtensions
{
    public static bool IsPayingCustomer(this Customer customer)
    {
        return customer.TotalSpent > 0;
    }
}
Enter fullscreen mode Exit fullscreen mode

we can write

public implicit extension CustomerExtensions for Customer
{
    // Add a property to a class you don't control
    public bool IsPayingCustomer => this.TotalSpent > 0;

    // Add a static method
    public static Customer Parse(string json) 
        => JsonSerializer.Deserialize<Customer>(json);
}
Enter fullscreen mode Exit fullscreen mode

No state or memory, just syntactic sugar for better readability. In the background the property is still an extension method.

var customer = Customer.Parse("{\"TotalSpent\": 100}");

var oldMethod = customer.IsPayingCustomer();

var newProperty = customer.IsPayingCustomer;
Enter fullscreen mode Exit fullscreen mode

2. The field keyword (C# 14)

It isn't required anymore to define a backing field to have some logic in getter/setter.
Just use the field keyword (be careful not to name anything 'field' in the class) and get the implicit backing field.

public string Name
{
    get => field;
    set => field = value?.Trim();
}
Enter fullscreen mode Exit fullscreen mode

3. File-based apps (.NET 10)

Do you have a console solution (or several) just for various small tools?
Now instead we can just run a single .cs file with dotnet run mytool.cs, without the need for any .sln or .csproj.
Write your single file like

// Add nuget packages with the special syntax
#:package Newtonsoft.Json@13.0.3

// Still need to add using statements
using Newtonsoft.Json;  

// Access command line arguments
var allArgs = Environment.GetCommandLineArgs();
Enter fullscreen mode Exit fullscreen mode

4. OrderedDictionary<TKey, TValue> (.NET 9)

We now have a kind of a named list in shape of OrderedDictionary<TKey, TValue>.
The elements can be both accessed by key and by index.

var laundryRoom = rooms[17];

var diningRoom = rooms["dining"];
Enter fullscreen mode Exit fullscreen mode

The order of elements is the order of insertion, so 0 is the first inserted element.


5. Enumerable.Index() (.NET 9)

A tiny but sweet sugar: instead of writing a for loop

for (int i = 0; i < items.Count; i++)
{
    var item = items[i];
    // act
}
Enter fullscreen mode Exit fullscreen mode

we can use foreach with IEnumerable and still get the index variable:

foreach (var (index, item) in items.Index())
{
    // act
}
Enter fullscreen mode Exit fullscreen mode

6. CountBy and AggregateBy LINQ (.NET 9)

Another sweet addition:

// old count of items by status
var countByStatus = items.GroupBy(x => x.Status)
    .Select(g => new { g.Key, Count = g.Count() });

// new
var countByStatus = items.CountBy(x => x.Status);
Enter fullscreen mode Exit fullscreen mode
// old sum of amounts by status
var aggregateByStatus = items.GroupBy(x => x.Status)
    .Select(g => new { g.Key, Sum = g.Sum(x => x.Amount) });

// new
var aggregateByStatus = items.AggregateBy(
    x => x.Status,              // Key selector
    seed: 0m,                   // Initial value
    (sum, x) => sum + x.Amount  // Aggregation logic
);
Enter fullscreen mode Exit fullscreen mode

Apart from just being more readable, these methods skip the intermediate grouping allocation.


7. CompareOptions.NumericOrdering (.NET 9)

Finally we can sort string and have "file2" come before "file10", thanks to CompareOptions.NumericOrdering:

var sorted = myStrings.OrderBy(s => s,
    StringComparer.Create(CultureInfo.InvariantCulture, 
        CompareOptions.NumericOrdering));
Enter fullscreen mode Exit fullscreen mode

That's my list. Do you know other features people should use more often?

Top comments (0)