Making code more readable with anonymous functions

Posted by Filip Ekberg on October 5 2011 8 Comments

If you come from a world filled with JavaScript you might be used to seeing the click handler logic defined at the same place as where you defined the click handler itself. For instance, look at this code:

$("#submit").click(function(){
    performPostAndRedirect();
});

I think it’s safe to say that this kind of code is very usual and that it’s nothing wrong with it, in fact, it’s easy to read and easy to understand and for me readability is something that is very important.

So how does this apply to C# development?

Look at the following code from a WPF-application:

var button = new Button();

button.Click += new RoutedEventHandler(button_Click);

This can be simplified a little bit, you actually don’t need to write the “newRoutedEventHandler”-part and nowdays you can just write:

button.Click += button_Click

Now this indicates that we have a method called button_Click that looks somewhat like this:

void button_Click(object sender, RoutedEventArgs e)
{
    throw new NotImplementedException();
}

In most of the cases that I’ve seen, you don’t want to do any actual logic inside the event-handler anyways, you might just want to fire off a method that starts off some task for you, or validate data. But this is rarely done inside the event handler itself, at least it shouldn’t be.

So, how can we make this easier on the eyes and just navigate to the Click event assignment and get a feeling of what is happening?

By using anonymous functions!

First of all you can write something like this:

button.Click += (object sender, RoutedEventArgs e) => { ValidateInput(); };

This can be simplified though and end up like this:

button.Click += (sender, e) => { ValidateInput(); };

Even if you do more than one method-call in the event handler (when using anonymous functions) I think this is a pretty nice approach, it’s less lines and you get an idea of what actually happens by just looking at that line of code. You don’t have to navigate down to the event-handler itself to see what’s going on.

This isn’t the only way you can use anonymous functions though, I use it frequently when I create new tasks like this:

Task.Factory.StartNew(() =>
                            {
                                PerformTimeConsumingOperation();
                                ValidateOperation();
                            });

Again, I think it would be redundant to do otherwise, to have a separate method that you call to actually start the real work, this is less code and more readable! At least in my eyes.

I hope you found this interesting and if you have any thoughts please leave a comment below!

Vote on HN

8 Responses to Making code more readable with anonymous functions

  1. IndyNo Gravatar says:

    It’s a bit easier to have a named function when you have to unhook an event handler in C#. Hooked event handlers are a major cause of leaks in C#.

  2. Filip EkbergNo Gravatar says:

    I would say it depends, often less code is better because it’s more readable and less error prone. In this case it might be more error-prone to use an anonymous function though.
    I did some looking around and it’s rare that you will have a memory leak because of an event, it’s possible but it’s rare and depends on what you are doing. I found a post on StackOverflow by Jon Skeet where he basically said: “You don’t always have to unsubscribe if you think about what the subscriber do”.
    Which means that if you are just strict with what the subscriber do, you can avoid memory leaks and have less and more readable code!

  3. John TantaloNo Gravatar says:

    it’s easy to read and easy to understand

    As somebody with a JavaScript background, that code is painful to read and screams to be refactored.

    I would write it as,

    $(“#submit”).click(performPostAndRedirect);

  4. Matt BrownNo Gravatar says:

    John – I would agree if there is a separate function, as in the example. However, I think Filip is intending to use that function as shorthand for “Do Stuff Here”. In the case where you don’t have a single function call, instead you have a few lines of code, the example works quite well.

  5. Tyler HutchisonNo Gravatar says:

    As somebody with a Javascript background, that code is perfectly fine to read and is not screaming for anything.

    If it were filled with nested if/else statements, duplicated code, or some sort of inappropriate pattern… then it would be screaming to be refactored.

  6. Robert RossneyNo Gravatar says:

    If I see a WPF application in which event handlers are being assigned to buttons in code, my first thought is not “Would anonymous functions make this more readable?” but “Shouldn’t this button’s command be bound to a property in the view model?” In WPF, if you’re manipulating buttons in code, you’re probably doing it wrong.

  7. Filip EkbergNo Gravatar says:

    Hi Robert,
    I totally agree with you, although this article is not about how you should assign events in either JavaScript or .NET, using events in the example is just to have a common ground that people recognize. The article is more about how you can remove redundant code to make things more readable than suggesting how you do your event handling in either of the previously stated.

  8. Grant EagonNo Gravatar says:

    I can understand uses for both cases. My usual approach is to use anonymous functions for simple things. If I need to do something more complex where possible routes through the code become harder to decipher, I usually just break it up for the sake of the reader (even if I’m the only one who will ever read it)..

    Code that’s easy to read is what I prefer. I am not trying to write the smallest code ever, just to prove a point. That’s what minifiers, obfuscators and compilers are for.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>