Fun with Func, lambdas and closures

I had a need to encapsulate a method and execute it in a loop (ideally by an external component) for rudimentary retry logic.  I further didn’t want to be confined to a specific method signature.  In other words, I wanted a class to be able to call a function generically without having to know the method signature but still have a consistent return type.

Turns out, it was pretty easy to pull off.  Define a Func<T> as your delegate for the routine you want to call.  Then, define another Func<T> that is assigned to a lambda (or you could use an anonymous method) which calls the Func<T> previously specified.  You’ve just created a closure, so now you can toss that little Gem off to some class that accepts the signature of the second Func<T> and loop around, executing that function over and over.  I haven’t cracked the code open yet in Reflector, but my understanding is this all gets boiled down to compiler slight of hand, creating types for all this, and I believe stack state is pushed onto the heap (along with the *this* pointer).

Example (toss in a console app):

class Program

    {

        private string id;

 

        static void Main(string[] args)

        {

            Program program = new Program();

            program.DoStuff();

 

            Program program2 = new Program();

            program2.DoStuff();

        }

 

        private void DoStuff()

        {

            this.id = Guid.NewGuid().ToString();

 

            Func<string, string> myFunction = this.Echo;

            Func<string> myClosure = () => myFunction(“Hey there!”);

 

            string[] messages = this.RunThreeTimes(myClosure).Split(“,”.ToCharArray());

 

            foreach (string message in messages)

            {

                Console.WriteLine(message);

            }

 

        }

 

        private string Echo(string message)

        {

            return string.Concat(message, this.id);

        }

 

        private string RunThreeTimes(Func<string> bundleOfJoy)

        {

            StringBuilder sb = new StringBuilder();

 

            for (int i = 0; i < 3; i++)

            {

                sb.Append(bundleOfJoy.Invoke() + “,”);

            }

 

            return sb.ToString().TrimEnd(“,”.ToCharArray());

 

        }

    }

 

 

1 thought on “Fun with Func, lambdas and closures

Leave a comment