Click here to Skip to main content
15,886,362 members
Articles / Programming Languages / C#
Tip/Trick

Passing Delegates With Any Signature to a Method

Rate me:
Please Sign up or sign in to vote.
4.36/5 (6 votes)
17 Jul 2015CPOL 12.8K   9   4
A simple tip to pass a delegate with any signature to a method

Introduction

This is a simple trick to pass a delegate with any signature to another method to consume it.

Using the Code

Before I go further with this, I just want to thank Andreas Gieriet, one of the forum members for his help with this.

If we use the closure concept of lambda expressions, we don't actually even have to pass parameters other than the anonymous delegates themselves.

The following two wrappers cater for Action and Func...

C#
public static TReturn FuncWrapper<TReturn>(Func<TReturn> function)
{
   Console.WriteLine("FUNCTION: Common code before method logic");
   TReturn result = function();
   Console.WriteLine("FUNCTION: Common code after method logic");
   return result;
}

public static void ActionWrapper(Action method)
{
    Console.WriteLine("ACTION: Common Code before method logic.");
    method();
    Console.WriteLine("ACTION: Common Code after method logic.");
}

... and can be called as follows:

C#
private static void Main(string[] args)
{    
    DateTime dateOfBirth = new DateTime(1994, 12, 25);
    string shortDate = dateOfBirth.ToShortDateString();
    
    // We can pass a function with any signature to the function wrapper like this.
    int x = 1;
    int y = 2;
    int z = FuncWrapper<int>(() => SumTwoIntegers(x, y));
    Console.WriteLine(string.Format("The sum of {0} and {1} is {2}.", x, y, z));

    Console.WriteLine();

    // We can declare and execute an inline function and pass it to the function wrapper like this:
    string calcAgeResult = FuncWrapper<string>(() => 
    {
        Console.WriteLine(string.Format("Calculating age for date of birth {0}.", shortDate));
        int ageInYears = (int)(DateTime.Now.Subtract(dateOfBirth).TotalDays/365.25);
        return string.Format("Someone born on {0} is {1} years old.", 
            shortDate, ageInYears);
    });
    Console.WriteLine(calcAgeResult);
    
    Console.WriteLine();
    
    // We can pass some ad hoc code to the action wrapper like this
    ActionWrapper(()=> {
        Console.WriteLine(string.Format("INSIDE VOID: Date of birth previously used was {0}", 
            dateOfBirth.ToShortDateString()));
    });
}

public static int SumTwoIntegers(int x, int y)
{
    Console.WriteLine("Inside the SumTwoIntegers() method");
    return x + y;
}

This will produce the following output:

FUNCTION: Common code before method logic
Inside the SumTwoIntegers() method
FUNCTION: Common code after method logic
The sum of 1 and 2 is 3.

FUNCTION: Common code before method logic
Calculating age for date of birth 25/12/1994.
FUNCTION: Common code after method logic
Someone born on 25/12/1994 is 20 years old.

VOID: Common Code before method logic.
INSIDE VOID: Date of birth previously used was 25/12/1994
VOID: Common Code after method logic.

Points of Interest

The nice thing with this implementation is that you can use variables from the calling method in the closures as they close over them. The variables are shared. We just have to be careful how we use the shared variables so that we don't unintentionally change them.

History

  • 15th July, 2015 - Initial article
  • 17th July, 2015 - Simplified, and downgraded to tip
  • 19h July, 2015 - Further simplification

License

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


Written By
Software Developer (Senior) Independent Contractor
Australia Australia
I started off as a VB3 programmer after completing a COBOL course in the mid 90's. After learning COBOL, VB was a breath of fresh air and a lot more "fun" to work with. My big break came when I landed on a big VB5/6 project in 1998. I worked under a couple of good guys and learnt a lot from them on the project.

When .NET was released, I started out as a VB.NET developer working on various Windows Forms as well as ASP.NET Projects. It didn't take long to make the transition to C# and today I'm more comfortable with C# than VB.NET. I've also had the fortune to work with SharePoint 2003-2013 quite a bit and love it as a platform.

Programming is an awesome and FUN challenge that I still enjoy after almost 20 years in the field, and I constantly strive to become better at it.

Comments and Discussions

 
QuestionMS advises to *not* directly use *Delegate* Pin
Andreas Gieriet19-Jul-15 9:43
professionalAndreas Gieriet19-Jul-15 9:43 
QuestionWhy delegates? Pin
lemur17-Jul-15 22:50
lemur17-Jul-15 22:50 
AnswerRe: Why delegates? Pin
OneWinsto19-Jul-15 16:57
OneWinsto19-Jul-15 16:57 
I see your point. In fact when I read 'batch job' and 'common logic' my first thoughts were command pattern and template method.

Maybe Steven didn't want to use an OO approach, for whatever reason. Or just wanted to play with the delegate thing Smile | :)
AnswerRe: Why delegates? Pin
John Brett19-Jul-15 20:48
John Brett19-Jul-15 20:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.