Until recently, I thought doing any kind of functional programming in C# was a nightmare. The syntax for using delegates always seemed very clumsy to me. I would start with this grand idea of passing in a delegate to be called when I wanted, but would end up stumbling over the syntax for hours on end. Coming up through the ranks of .NET programming since v1.1, all of those examples of using delegates made things like asynchronous programming seem super hard. If only there was a better way...

Over the past few years working at Skookum, I've had the privilege of working on projects outside the .NET world. Getting outside of my comfort zone and taking a stab at things like nodejs has really helped me better understand C#. One of those things has been the concept of passing functions around as variables or objects. In a language like JavaScript where you are doing a lot of things like AJAX calls, the concept of a callback function is a very common practice. In C#, however, it can get pretty hairy until you discover the underpinnings of the lambda.

C# Lambdas

Most C# dev's use lambdas all the time in writing LINQ queries. Since .NET 3.5 this has become a very common practice: var result = someList.Select(it => it.IsActive); But to really understand its power you have to break it down to the components that make it up. Looking to the MSDN documentation for the .Select method you see a method signature that doesn't look exactly like you would expect.

~ csharp public static IEnumerable Select(
this IEnumerable source, Func selector )

What is this Func<TSource, TResult> selector thing? Why didn't we have to specify those generic classes <TSource, TResult> when calling Select? I believe the confusing part of this is that the C# compiler will infer the Generic Types for you most of the time when using Select. So this could be rewritten as .Select<SomeClass, bool>(it => it.IsActive), which says:

  • We're selecting from an IEnumerable of type SomeClass(SomeClass maps to TSource above).
  • Passing an item in that collection (defined as it) to the lambda it => it.IsActive.
  • Then returning the bool property IsActive(bool maps to TResult above).

Since most of the time the generic type declaration on Select is not required, we don't realize we are actually defining the return type and the parameter type(s) of the lambda. This is a key concept to being able to reuse the meat of a lambda which is the Func.

The Func

A Func in C# is a way to define a method in-line that has a return value. There is a similar concept of an Action that doesn't have a return value, but we'll get to that in a sec. The return value's type is always the last generic parameter on the Func's definition. All the other generic parameter types are the parameters you are passing to the Func. So in theory, if we want to reuse the selector from the above code in more than one place, we can define it as a Func:

~ csharp Func isActiveSelector = it => it.IsActive;

Now when calling our Select on SomeClass, we can pass it our Func:

~ csharp var result = someList.Select(isActiveSelector);

In this simple example, it doesn't make that much difference as far as the code goes, but if I was using a more complex return type, this could be crucial for code maintainability. All in all though, reusing selectors isn't all that sexy. Where it gets interesting for me is when it dawned on me that I could define a Func or an Action and pass it in as a parameter to a method (like so easily done in JavaScript).

Imagine there is a utility method that I would like to define, that would wrap some database calls in a transaction. In this method I know I'm going to always have to open a transaction, run some code that will always be different, and then commit or rollback the transaction. Now how do I do this, you say? Did I hear inheritance? Nah, lets do it with an Action:

~ csharp public void WrapInTransaction(Action dbCalls)
{ using (ITransaction transaction = _session.BeginTransaction()) { try { dbCalls(); transaction.Commit(); } catch(Exception exception) { //do something with the exception transaction.Rollback(); } } }

Then I can call this method with a nice, cozy lambda:

~ csharp WrapInTransaction(() =>
{ Update(entity); LogToAuditTable(entity); });

A couple things to note about this syntax here.

  • An Action can be used with no parameters, which is what you see in WrapInTransaction(Action dbCalls).
  • A lambda expression that doesn't take any parameters starts with () =>.
  • Lambdas can also be multiline! To create a multiline lambda, just open the block with a { (and be sure to close it with a }). Also each line in a multiline lambda has to be terminated with a ;.

Boom! We are now doing some functional programming in C#. This is awesome because it can really help reduce code duplication. If you catch yourself always starting or ending a method with the same lines, you can refactor that into a method that takes in an Action or Func. Or take this and apply it to the Task paradigm and do some cool asynchronous programming.