Anonymous methods: how to factorize surrounding statements like try-catch

 

Here is the translation of one of my old french articles at a moment when I was trying to find what I could do with anonymous methods :p !

Here is the idea:

Let's imagine we would like to centralize exception management. In numerous program (like windows API), a classical solution consist in implementing methods returning an integer. It's quite easy to define a rule like: -1 equals "no exception" and 0 and greater are representing the error number (or code).

Then it becomes easy to define a ShowError(int errorCode) method to centralize error management. Using this pattern, we still have to write try-catch statements every time because they just can not be factorized.

 

 private int AddCustomer(string param)
{
    try
    {
        int i = Convert.ToInt32(param);
    }
    catch
    {
        return 1;
    }
    return 0;
}

private void ShowError(int value)
{
    if (value != 0)
        switch (value)
        {
            case 1:
                //error 1
            case 2:
                //error 2
            default:
                MessageBox.Show("Error has been raised:" + value.ToString());
                break;
        }
}

The call now looks like:

 

 ShowError(AddCustomer("blabla"));

The idea is to use C# 2.0 anonymous methods to delay critical code execution. Then we have time to surround the delegate referencing the anonymous method with any kind of surrounding statement like try-catch. We will use the simplest delegate as possible (void()). Let's remind that in an anonymous method, we can access to the same scope elements than the hosting method, so having no parameter in our delegate is not a problem.

 

 public delegate void SimpleDelegate();

Then we can implement a unique method for exception handling including our try-catch statement.

 

 private void SafeCall(SimpleDelegate d)
{
    try
    {
        if (d != null)
            d();
    }
    catch (Exception e)
    {
        MessageBox.Show("Error has been raised:" + e.Message);
    }
}

The call becomes really simpler:

 string s = "blabla";

SafeCall(delegate
{
    int i = Convert.ToInt32(s);
});

We can imagine using this same pattern to factorize transactions:

 

 InTransaction(delegate
{
    AddCustomer();
});