Functional C#

C# is a multi-paradigm programming language. Recently, the course has been set towards new functional constructions in C#. We can go further and add other extension methods that allow writing less code without ‘climbing’ in the F# territory.

PipeTo

As Pipe Operator is not going to be included in the upcoming next release, we can write the code using the method.

Imperative variant

With PipeTo

As you can see, in the first variant, I needed to cast a look back at a the variable declaration and then proceed to Ok, while with PipeTo, the execution flow is running strictly left to right, top to bottom.

Either

In the real world, there are more branching algorithms, rather than the linear ones:

It does not look so good anymore. Let’s fix it using the Either method:

Add a null check overload:

Unfortunately, the type inference in C# is not perfect. That’s why I had to add an explicit cast to IActionResult.

Do

Get methods of controllers are not supposed to create side effects. However, sometimes they are really needed.

With such code organization, it will be impossible to miss this effect with Do during code review. Though, using DO is a point at issue.

ById

Do not you think that constantly repeating q.Where(x => x.Id == id).SingleOrDefault() is very annoying?

What if I do not want to get the whole entity and I need projection:

I think that by now the (IActionResult)new NotFoundResult(“Not Found”)) method is overused. So, you can easily write the OkOrNotFound method by yourself.

Paginate

Perhaps, there are no applications that work with data without paging.

Instead of:

You may write the code in the following way:

IQueryableFilter

As it has been discussed, I suggested a different way to group Where and OrderBy in LINQ statements, which might be interesting for you:

It makes sense to apply Where before the Select clause, and sometimes – after.

Add the MaybeWhere method, which works both with IQueryableSpecification, and Expression<Func<T, bool>>

Now, we can write a method that takes into account different variants:

or you can use Queryable Extensions AutoMapper:

If you do not like to use IPaging, IQueryableSpecififcation and IQueryableOrderBy simultaneously for one object, you can write the following code:

As a result, we get three rows of code for the method that filters, sorts and provides paging for any data sources that support LINQ.

Unfortunately, signatures of methods in C# look humongous due to the load of generics. Luckily, we may omit method parameters in the application code. The same is with the signatures of LINQ extensions. How often do you specify the type that the Select clause returns? With var, we can avoid this torture.

Max Arshinov

Max Arshinov

Chief Executive Officer (CEO) at hightech.today
Max Arshinov has been developing applications for business for more than 10 years. He had been a developer, PM, and head of the testing department until he set up his own company "Hightech". Now, Maxim is a CEO of the company.
Max Arshinov

Latest posts by Max Arshinov (see all)

Max Arshinov

Max Arshinov has been developing applications for business for more than 10 years. He had been a developer, PM, and head of the testing department until he set up his own company "Hightech". Now, Maxim is a CEO of the company.

  • VIMce

    Really nice functional solutions to some common problems.

    These solutions though, although elegant, might confuse a junior who has to maintain your code a year from now. As someone who has been writing c# for 16 years I really had to pause to soak in what those extension methods were doing.

    Sometimes a long and boring SingleOrDefault or Where(x=>x. Id ==… Is much easier to understand for a team.

    That being said, I really like what you’ve done here. They will have a place in my memory for when they are needed ☺️

    • Maxim Arshinov

      Totally agree about. So before using this stuff in production code we introduced it to the team and asked what they expect these extensions are doing. We decided not to use extensions which were not clear and renamed some methods to avoid any misunderestanding.