SECRET OF CSS

My Top 7 Custom Extension Methods for .NET 7 and C# | by Tobias Streng | Oct, 2022


Improve your fluent coding with these essential extension methods!

Photo by Ryland Dean on Unsplash

Since I had gotten to know about extension methods, I continuously found new possibilities to make my life as a coder easier. Extension methods are a perfect application of the O in SOLID — The Open Closed Principle. A class should be as simple as possible and only expose properties and methods to its outside when they are really needed by other components.

Through extension methods, you can implement additional methods for your class, without the need of changing the class itself! This is perfect for recurring methods that take the class as an argument.

Implementing an Extension method is pretty easy. Have a look at the following example:

This implements the ForEach() method on every IEnumerable<T> (introduced by the this keyword) just like you know from the List<T> type. The only thing you need to do, to have access to this method, is to add a reference to the respective namespace, which is System in this case.

Since .NET 6, Microsoft has implemented a few extension methods for IEnumerable<T> that I previously had on my top list, including DistinctBy() and Chunk(). However, as of .NET 7, I am still missing some very important methods, especially to handle collections of Tasks.

Without further ado, here are my most used extension methods that I use in .NET 7:

The first extension method is my favorite one. How many times did you add a new try-catch block around a just-created method and became a little annoyed by it destroying the look? Here is a very neat solution for when your method returns a Task or Task<T>:

Now you can simply write:

var result = await GetSomethingAsync().TryAsync();

And your method will automatically be wrapped in a try-catch block. Additionally, you can provide an errorHandler for additional side-logic like logging. The Result, which these methods return can then be checked for success and you can continue your logic.

By the way, theResult or Result<T> you can spot in these methods is from my previous article:

Having more than one Task or Task<T> in a collection is a bit inconvenient to handle in the normal way. You need to call Task.WhenAll(tasks) which throws me a bit out of the flow, as it is not in a fluent style. Here’s what it looks like:

Now I can simply have any collection of Tasks and simply write:

var results = await tasks.WhenAllAsync();

The next extension method is even saving you a few more lines of code and gives you the ability, to execute each task one by one. This might be useful in scenarios, where you may not execute many tasks in parallel.

Last but not least, there might be a use case where you can execute tasks in parallel but there might be a limit of max. parallel workers. For this case, I have the following extension method:

With the degree parameter, you can specify how many tasks should be executed in parallel.

This one is also a fluent extension, but this time for a single Task or Task<T>.

With this extension method, you are able to fluently map a Task<T1> to a Task<T2> similar to the Enumerable.Select() method.

A similar method is DoAsync() , but instead of transforming a task, you can execute side-logic with the tasks result without altering its return value.

The very last is an extension method I sometimes use for concatenating strings for logging. Normally, you could use string.Join() for this, but again, this is not fluent and throws me out of the flow.

Not technically extension methods, but also very useful to save some code, are my abbreviation methods:

To use them easily, you have to create a special file (I normally call it GlobalUsings.cs) on your root level and put the following line in it:

global using static System.Abbreviations;

The Arr method is an abbreviation for creating a new array. Normally, this would take a very ugly code, as shown below:

var arr = new [] { param1, param2,... };

Now you can simply write it like this:

var arr = Arr(param1, param2,... );

Which looks prettier and you do not have to do acrobatics with your fingers on your keyboard.

How often did you just want to add a simple try-catch block around a new method and it just feels ugly, due to it taking so much space in your code? Here is a solution with the abbreviation method Try().

In its most shortened form you can write:

Try(TestMethod);

where TestMethod is a method not taking any parameters. This enables you to write extremely short code and eliminate those nasty try-catch blocks.

For async methods, I would recommend you use the extension method TryAsync from above, as it is in the fluent style.



News Credit

%d bloggers like this: