Monday, May 27, 2013

Using Actions to clean up your code

I am a firm believer of DRY “If you are doing the same thing thrice, you are doing it wrong” . Within reasonable effort ofcourse.

So when I see code like this:

List<string> permissions = new List<string>();
// The ones we care about:
if (Session.HasPermissions(Permission.AdministrationSetPoints))
{
    permissions.Add(Permission.AdministrationSetPoints.ToString());
}
if (Session.HasPermissions(Permission.Administration))
{
    permissions.Add(Permission.Administration.ToString());
}

There is no wonder that I want there to be a function to abstract out the if conditions. But creating a new function at class level looks a bit dirty. Not only do you have a new function that is only called from one place but you need to pass in a ref argument (permissions list). Later on its unclear at first sight (without reading xml comments perhaps) why this new function was created. Additional constraints like making sure your private functions are at the end may increase the distance between your original function and this new function. 

Lucky for us C# 3.0 gave us an excellent solution with inline lambdas:

List<string> permissions = new List<string>();

Action<Permission> addPermission = (Permission p) =>
    {
        if(Session.HasPermissions(p))
            permissions.Add(p.ToString());                   
    };
           
// The ones we care about:
addPermission(Permission.AdministrationSetPoints);
addPermission(Permission.Administration);

Notice that:
  • the action (addPermission) does not need to be passed in the permissions object since the outer scope variable is available.
  • The function is declared closer to where it is used and you can tell at first look why it was created.


To be honest. For this I was inspired by JavaScript closures.