Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

DRY-ing up your Code with Delegates

4.82/5 (6 votes)
18 Sep 2017CPOL2 min read 15.3K  
Using the Action(T) delegate to reduce repetitive coding

Introduction

There are many times that I've been asked about delegates and lambda expressions, specifically on the practical use or implementation of them. One of the more important aspects of these features is creating code that provides parallel, if not improved, levels of functionality with less repetition and bloat. One of the best practices in object-oriented programming is the idea of refactoring, which is reorganizing code into a more modular form based on the frequency and use.

Using the Code

So here's a quick example of code that performs some operations on a list of numbers:

C#
class Program 
{
    static void Main(string[] args) 
    {
        List<int> numbers = new List<int> { 2, 4, 6, 8, 10 };
        foreach (int num in numbers) {
            Console.WriteLine("{0} x 2 = {1}", num, num * 2);
        }
        
        numbers.Clear();
        numbers.AddRange(new int[] { 1, 3, 5, 7, 9 };
        foreach (int num in numbers) {
            Console.WriteLine("{0} x 2 = {1}", num, num * 2);
        }
    }
}
VB.NET
Public Class Program
    Public Shared Sub Main(ByVal args() As String)
        Dim numbers As List(Of Integer) = New List(Of Integer) From { 2, 4, 6, 8, 10 }
        For Each num In numbers
            Console.Writeline("{0} x 2 = {1}", num, num * 2)
        Next

        numbers.Clear()
        numbers.AddRange({ 1, 3, 5, 7, 9 })
        For Each num In numbers
            Console.Writeline("{0} x 2 = {1}", num, num * 2)
        Next
    End Sub
End Class

We create a list of integers, iterate through the list showing each value and the result of the value multiplied by two, clear and repopulate the list, and perform the same iteration. While this code is valid, and probably commonly seen, it can be reorganized and reduced using delegates. Let's take a look at this code with some revisions:

C#
class Program 
{
    static void Main(string[] args) 
    {
        List<int> numbers = new List<int> { 2, 4, 6, 8, 10 };
        Action<int> writeMultipliedValue = (num => Console.WriteLine("{0} x 2 = {1}", num, num * 2));
        numbers.ForEach(writeMultipliedValue);
        
        numbers.Clear();
        numbers.AddRange(new int[] { 1, 3, 5, 7, 9 };
        numbers.ForEach(writeMultipliedValue);
    }
} 
VB.NET
Public Class Program
    Public Shared Sub Main(ByVal args() As String)
        Dim writeMultipliedValues As Action(Of Integer) = _
                 Sub(num) Console.WriteLine("{0} x 2 = {1}", num, num * 2)

        Dim numbers As List(Of Integer) = New List(Of Integer) From { 2, 4, 6, 8, 10 }
        numbers.ForEach(writeMultipliedValues)

        numbers.Clear()
        numbers.AddRange({ 1, 3, 5, 7, 9 })
        numbers.ForEach(writeMultipliedValues)
    End Sub
End Class

A point to note is the declaration of the Action(T) delegate which is assigned the value of a lambda expression. The lambda expression contains the display code that was in the foreach loop in the previous example. Since we know that both of the foreach loops performed the same task, it stands to reason that this code could be placed in a separate method and called as needed.

The List(T) class provides a method, ForEach, which performs an action on each element contained therein, which accepts an Action(T) instance for its only parameter. We then use the Action(T) delegate we assigned as the value supplied to the parameter of the ForEach method, in effect creating the same functionality as our foreach loops in the previous example.

Using delegates in this manner is a great way to keep your code short, sweet, and to the point. If you're not familiar with delegates, lambda expressions, or the DRY principle, I'd recommend reading up on these topics:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)