Friday, December 3, 2010

C# Delegates as Method Parameters

Let's say you have 2 methods that go through similar steps:

public string GetPrevItem()
 {
    if (IsValidPrevEntry())
    {
        string item = GetPrevString();
        SetProperties();
         return item;
    }
   else
       return null;
 }

public string GetNextItem()
{
    if (IsValidNextEntry())
     {
        string item = GetNextString();
        SetProperties();
        return item;
     }
     else
       return null;
 }
 
These 2 methods essentially do the same thing. First, they check for some condition, and if the condition evaluates to true, they call another method, set some properties, and return a string. We can use C# delegates to refactor these 2 methods into one. Here is how you do it:
Declare 2 delegates whose signature matches the methods we want to replace:
  delegate bool IsValid();
  delegate string GetItem();
Create a method that will use the delegates:

 private string GetMyItem(IsValid isValid, GetItem getItem)
 {
   if (isValid())
   {
        string item = getItem();
         SetEventProperties();
         return item;
   }
   else
       return null;
  }       
An alternative method signature is as follows:
 private string GetNavItem(Func<bool> isValid, Func<string> getItem)
This way we don't have to declare delegates separately.

Now, we can call the new method, passing the methods that we called before refactoring, as parameters:
string strPrev =   GetMyItem(IsValidPrevEntry, GetPrevString);
string strNext =   GetMyItem(IsValidNextEntry, GetNextString);
An interesting discussion of delegates can be found on the stackflow.