Getting Functional with C#
As C# has matured, it has consistently been adopting elements of functional programming. In many was — as I’ve discussed before — C# continues to converge with TypeScript and JavaScript.
I have a small repo where I share some of my experiments with the more functional side of C#:
Inspired by a question in a Reddit post (you can see my original response there), let’s take a look at the latest additions to this lab.
Using Lambda Expressions
We can start our lab by creating lambda expressions to “alias” Console.WriteLine
for convenience:

This can be a really handy way to reduce visual clutter in your code. I use “alias” in quotes because all we’re doing is writing a function called log
, but using lambda expressions and local functions makes it much more compact.
A List of Lambda Expressions
Our first example is a simple array of functions. We can loop over the array and invoke each function with our inputs:

Use cases: validators, when running different calculations to compare results for different algorithms, quick-and-dirty lightweight Chain of Responsibility.
Named Lambda Expressions
We can also name the functions as strings by putting them into a dictionary:

This should look very similar to anyone who writes JavaScript or TypeScript (though a bit more verbose here in C# as the compiler cannot infer the type of namedFunctions
since C# has more than one dictionary type (idea: could we get it to default to Dictionary<string,string>
? That would be amazing.)
Use cases: replace reflection with a more performant option by using the string indexer instead of reflection on an attribute.
References to Lambda Expressions
We can also use a list of references to lambda expressions:

Accepting an Arbitrary Number of Parameters
By taking advantage of LINQ, we can accept an arbitrary number of parameters:

Wrap in Another Lambda Expression
We can wrap the list of lambda expressions in another lambda expression:

Return Results In a Dictionary
We can return the results as a dictionary which can be useful if we are interfacing via JSON to a front-end:

Use cases: dynamic generation of JSON results to a front-end, validation where you want to have a key value identifying which validator failed.
Returns Results In a Tuple
We can also grab the results as a tuple:

Execute by Number of Parameters
Using C# switch expressions, it is possible to select an output based on the number of parameters:

I really love the expressiveness of switch expressions and the fact that while it is far more compact than the alternative, it doesn’t seem to lose any readability; I think it actually improves it.
Number of Parameters and Lambda Expressions
We can even combine the switch expression with lambda expressions:

Pattern Matching Switch Expression with Inline Lambda Expressions
Or write those same lambda expressions inline with the switch expression:

Execute Lambda by Parameter Type
One of my favorite things about switch expressions is that we can even switch by type and assign in one compact statement:

Tim Deschryver has a great set of examples of just how interesting pattern matching is in C#. By far, this is one of the best features of C#!
I hope that this little lab piqued your interest to explore the more functional side of C#. Many C# developers are either not aware of these features or actively avoid these features of the language 🤣. For me, these are some of the most interesting language features and the switch expression is one of the most versatile expressions in any language (well, at least the ones I work with!).
One of the best uses for lambda expressions and local functions is that it can simplify calls where you would otherwise need to shuttle extra parameters around. In other words, cases where you have an entry function with parameters (A, B, C) that might invoke a helper function that requires (B, C, D, E) where D and E are calculated in the entry function. Using lambda expression and local functions allow you to capture the scope without having to have overlapping parameter sets in your functions (and sometimes, those helper functions don’t really deserve their own top level method!).
Check out the repo and embrace the more functional aspects of C# and .NET!