Eric's Blog

Day to day experience in .NET
Welcome to Blogs @ IRM Sign in | Join | Help
 Search

Disclaimer

The content of this site is my own personal opinion and does not in any way represent my employer, it's subsideries or affiliates. These postings are provided "AS IS" with no warranties, and confer no rights.

This Blog

Keep Code DRY with Delegates and Lambda Expressions

I had a method that looked like this in my code:

public string Translate(string entity, string field)
{
    string key = Translator.GetKey(entity, field);

    if (translationCache.ContainsKey(key))
        return translationCache[key];
    else
    {
        string res = this.Translator.Translate(entity, field);
        translationCache.Add(key, res);
        return res;
    }
}

This code uses a cache mechanism that counts for most of the lines in the method. For a new requirement I needed to add an overloaded method that takes a single argument and calls an overloaded versions of Translator.GetKey and Translator.Translate methods, but the rest of the code would look the same. Of course I would like to keep the code DRY (Don’t Repeat Yourself). So how do you solve a problem when a single line of code in the middle of the method needs to be different, but the rest should be the same? Of course you could split the logic and create a couple of smaller methods that handles other parts of the code, but in this case it is hard to do that in a good way. Typically I would say that this code will be copied and pasted and then changing the line that needs to, but violating DRY. The way I solved the problem was to use a delegate as argument and invoke that on the line that differs. In this case I choose the Func<T>() delegate.

public string Translate(string name)
{
    return Translate(Translator.GetKey(name), () => this.Translator.Translate(name));
}

public string Translate(string entity, string field)
{
    return Translate(Translator.GetKey(entity, field), () => this.Translator.Translate(entity, field));
}

private string Translate(string key, Func<string> translation)
{
    if (translationCache.ContainsKey(key))
        return translationCache[key];
    else
    {
        string res = translation.Invoke();
        translationCache.Add(key, res);
        return res;
    }
}

Now I have a single private method that handles the caching part except for creating the key. The solution with taking the Func<string> delegate as a parameter is easily called by a using lambda expression in the public methods. Each expression calls the correct overloaded version of the Translate method.

Hope this helps you to find new ways to keep your code DRY, when extracting methods and other techniques, doesn’t fit that well.

Published den 10 januari 2010 11:42 by ericqu
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server, by Telligent Systems