Image for post
Image for post

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

public static TResult PipeTo<TSource, TResult>(
this TSource source, Func<TSource, TResult> func)
=> func(source);

Imperative variant

public IActionResult Get()
{
var someData = query
.Where(x => x.IsActive)
.OrderBy(x => x.Id)
.ToArray();
return Ok(someData);
}

With PipeTo

public IActionResult Get() => query
.Where(x => x.IsActive)
.OrderBy(x => x.Id)
.ToArray()
.PipeTo(Ok);

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

public IActionResult Get(int id) => query
.Where(x => x.Id == id)
.SingleOrDefault()
.PipeTo(x => x != null ? Ok(x) : new NotFoundResult(“Not Found”));

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

public static TOutput Either<TInput, TOutput>(this TInput o, Func<TInput, bool> condition,
Func<TInput, TOutput> ifTrue, Func<TInput, TOutput> ifFalse)
=> condition(o) ? ifTrue(o) : ifFalse(o);

public IActionResult Get(int id) => query
.Where(x => x.Id == id)
.SingleOrDefault()
.Either(x => x != null, Ok, _ => (IActionResult)new NotFoundResult(“Not Found”));

Add a null check overload:

public static TOutput Either<TInput, TOutput>(this TInput o, Func<TInput, TOutput> ifTrue,
Func<TInput, TOutput> ifFalse)
=> o.Either(x => x != null, ifTrue, ifFalse);

public IActionResult Get(int id) => query
.Where(x => x.Id == id)
.SingleOrDefault()
.Either(Ok, _ => (IActionResult)new NotFoundResult(“Not Found”));

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

Do

public static T Do<T>(this T obj, Action<T> action)
{
if (obj != null)
{
action(obj);
}

return obj;
}

public IActionResult Get(int id) => query
.Where(x => x.Id == id)
.Do(x => ViewBag.Title = x.Name)
.SingleOrDefault()
.Either(Ok, _ => (IActionResult)new NotFoundResult(“Not Found”));

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.

Liked the article? Continue reading here — https://bit.ly/2BWni6k.

Thank you for your time!

Written by

Awesome blog focused on databases and Microsoft, .NET and cloud technologies. http://codingsight.com/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store