Taylor's Blog

Atypical ramblings

Welcoming the delegates

I have started working through The Art of Unit Testing by Roy Osherove and came upon this test that took me a while to understand:

[Test] 
public void IsValidFileName_EmptyFileName_Throws()
{
    var ex = Assert.Catch<Exception>(() => la.IsValidLogFileName(""));                 
    StringAssert.Contains("filename has to be provided", ex.Message);
}

I was really confused about what was happening on line 4. Looking at the NUnit documentation, I saw that this is format for the Assert.Catch method:

T Assert.Catch<T>(TestDelegate code);

The method is going to return an exception, but it needs to be passed a TestDelegate first. We can see the syntax for a TestDelegate here:

public delegate Void TestDelegate ()

This seems strange because according to the code, Assert.Catch is being passed a lambda expression:

() => la.IsValidLogFileName("")

Well it turns out that Lambda expressions are a simpler syntax for anonymous delegates and can be used everywhere an anonymous delegate can be used. The Microsoft docs even say as much:

a lambda expression is just another way of specifying a delegate

The question is then, “what is a delegate?” From my research, a delegate is used in C# when you want to pass a function itself as a parameter. You often see people refer to a delegate as “a pointer to a function.” The syntax for creating a delegate is as follows:

<access modifier> delegate <return type> <delegate_name>(<parameters>)

And here is some example code using a delegate:

 class Program
 {
     public delegate void Print(int value);

     static void Main(string[] args)
     {
         Print printDel = PrintNumber;

         // or you can do this:
        // Print printDel = new Print(PrintNumber);

        printDel(100000);
        printDel(200);

        printDel = PrintMoney;

        printDel(10000);
        printDel(200);
    }

    public static void PrintNumber(int num)
    {
        Console.WriteLine("Number: {0,-12:N0}",num);
    }

    public static void PrintMoney(int money)
    {
        Console.WriteLine("Money: {0:C}", money);
    }
}

And here is the output:

Number: 10,000 
Number: 200 
Money: $ 10,000.00 
Money: $ 200.00 

Let’s understand what’s happening here.

  1. We are declaring a delegate called Print that takes an integer as an argument. We create a new instance of this delegate can call it printDel.
  2. We point printDel at the PrintNumber function.
  3. We call our delegate twice, passing it in two different values. It formats the numbers appropriately with commas as specified in the PrintNumber method.
  4. We then point printDel at the PrintMoney function.
  5. We call our delegate two more times and this time it formats the numbers for currency as described in the PrintMoney function.

So, in summary, if we use a delegate, we’re passing a pointer to chunk of code, whereas if we use a lambda, we’re passing the code directly (and anonymously). Lambdas are more convenient in this case because we don’t have to declare them or even give them a name.

Updated: January 8, 2019 — 6:07 pm

Leave a Reply

Your email address will not be published.

Taylor's Blog © 2015