Click here to Skip to main content
14,936,416 members
Articles / Programming Languages / C#
Tip/Trick
Posted 17 Jul 2015

Tagged as

Stats

11.2K views
9 bookmarked

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
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)

Share

About the Author

Steven Oberholzer
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 
See Delegate Class: [...] Most languages implement a delegate keyword, [...] therefore, users should use the delegate keyword provided by the language. [...]
So, your example with the Delegate class is not a good advise at all.
Regards
Andi
QuestionWhy delegates? Pin
lemur17-Jul-15 22:50
Memberlemur17-Jul-15 22:50 
AnswerRe: Why delegates? Pin
OneWinsto19-Jul-15 16:57
MemberOneWinsto19-Jul-15 16:57 
AnswerRe: Why delegates? Pin
John Brett19-Jul-15 20:48
MemberJohn 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.