Code Listing for ‘Delegate Syntax in C# for Beginners’

using System;

namespace DelegateSyntax
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.BasicExamplesWithDelegateTypes();
            p.ExamplesWithReturnValues();
            p.ExamplesWithEvents();
            p.ExamplesPassingParameters();
            p.ExamplesPassingDelegateParameters();
            Console.ReadLine();
        }

        private delegate void TestDel(string s);
        private delegate void TestDelNoParams();
        private delegate string TestDelReturn(string s);
        private delegate string TestDelReturnNoParams();

        // Test functions used for named method (not inline) syntax
        private void Test(string s)
        {
            Console.WriteLine(s);
        }

        private string TestReturn(string s)
        {
            return "Hello " + s;
        }

        private void BasicExamplesWithDelegateTypes()
        {
            // ORIGINAL .NET SYNTAX - NAMED METHODS

            // Explicitly create TestDel delegate - Test is the method we want called
            // with "Hello World 1" as the parameter.  Test just writes the parameter to the
            // console.
            TestDel td = new TestDel(Test);
            td("Hello World 1");

            // Implicitly create the TestDel delegate
            TestDel td2 = Test;
            td2("Hello World 2");

            // ANONYMOUS METHOD SYNTAX

            // Create the delegate inline with an anonymous method
            TestDel td3 = 
                delegate(string s)
                {
                    Console.WriteLine(s);
                };
            td3("Hello World 3");

            // Inline with an anonymous method can capture local variables in the
            // calling method (form a closure)
            // Note: using different delegate type that doesn't take a string parameter,
            // we're just capturing the message from the calling method
            string message = "Hello World 4";
            TestDelNoParams td4 = 
                delegate()
                {
                    Console.WriteLine(message);
                };
            td4();

            // LAMBDA SYNTAX

            // Expression lambda (one statement only), passing in a parameter
            TestDel td5 =  s => Console.WriteLine(s);
            td5("Hello World 5");

            // Statement lambda: can have multiple statements, again passing in a parameter.
            // Both expression and statement lambdas can capture
            // a variable from the calling method (form a closure), demonstrated here with message2
            string message2 = "Hello World 8";
            TestDel td6 =
                s => 
                { 
                    Console.WriteLine(s); 
                    Console.WriteLine("Hello World 7");
                    Console.WriteLine(message2);
                };
            td6("Hello World 6");

            // Expression lambda capturing variable, no parameters
            string message3 = "Hello World 9";
            TestDelNoParams td7 = () => Console.WriteLine(message3);
            td7();
        }

        private void ExamplesWithReturnValues()
        {
            // Explicitly create TestDelReturn delegate - TestReturn is the method we want called
            // with "World 10" as the parameter.  The TestReturn method returns "Hello " + this string
            // and we write the return value out
            TestDelReturn tdr = new TestDelReturn(TestReturn);
            Console.WriteLine(tdr("World 1"));

            // Implicitly create the TestDelString delegate
            TestDelReturn tdr2 = TestReturn;
            Console.WriteLine(tdr("World 2"));

            // Do it inline with an anonymous method
            TestDelReturn tdr3 =
                delegate(string s)
                {
                    return "Hello " + s;
                };
            Console.WriteLine(tdr3("World 3"));

            // Inline with an anonymous method can capture local variables in the
            // calling method (form a closure)
            // Note: using different delegate type that doesn't take a string parameter
            string message = "World 4";
            TestDelReturnNoParams tdr4 =
                delegate()
                {
                    return "Hello " + message;
                };
            Console.WriteLine(tdr4());

            // Expression lambda (one statement only): you CANT return a value from an 
            // expression lambda - not valid syntax
            //TestDelReturn tdr5 = s => return "Hello " + s;
            //tdr5("World 5");

            // Statement lambda: can have multiple statements, again passing in a parameter.
            // Both expression and statement lambdas can capture
            // a variable from the calling method (form a closure), demonstrated here with message2
            string message2 = "World 8";
            TestDelReturn tdr6 =
                s =>
                {
                    Console.WriteLine(s);
                    Console.WriteLine("Hello World 7");
                    return "Hello " + message2;
                };
            Console.WriteLine(tdr6("Hello World 6"));
        }

        private event TestDel TestDelEventHandler;
        public void ExamplesWithEvents()
        {
            // Named method
            TestDelEventHandler += new TestDel(Test);
            TestDelEventHandler("Hello World 20");

            // Simplified named method
            TestDelEventHandler = null;
            TestDelEventHandler += Test;
            TestDelEventHandler("Hello World 21");

            // Anonymous method
            TestDelEventHandler = null;
            TestDelEventHandler += 
                delegate(string s) 
                {
                    Console.WriteLine(s);
                };
            TestDelEventHandler("Hello World 22");

            // Expression lambda
            TestDelEventHandler = null;
            TestDelEventHandler += s => Console.WriteLine(s);
            TestDelEventHandler("Hello World 23");

            // Statement lambda
            TestDelEventHandler = null;
            TestDelEventHandler += s => { Console.WriteLine(s); };
            TestDelEventHandler("Hello World 24");
        }

        public void ExamplesPassingParameters()
        {
            CallTestDel(new TestDel(Test));  // Named method
            CallTestDel(Test);               // Simplified named method
            CallTestDel(delegate(string s) { Console.WriteLine(s); });  // Anonymous method
            CallTestDel(s => Console.WriteLine(s));  // Expression lambda
            CallTestDel(s => { Console.WriteLine(s); Console.WriteLine("Hello World 32"); });  // Statement lambda
        }
        private void CallTestDel(TestDel testDel)
        {
            testDel("Hello World 30");
        }

        public void ExamplesPassingDelegateParameters()
        {
            CallDelegate(new TestDel(Test));  // Named method
            CallDelegate((TestDel)Test);      // Simplified named method
            CallDelegate((TestDel)delegate(string s) { Console.WriteLine(s); });  // Anonymous method
            CallDelegate((TestDel)(s => Console.WriteLine(s)));  // Expression lambda
            CallDelegate((TestDel)(s => { Console.WriteLine(s); Console.WriteLine("Hello World 32"); }));  // Statement lambda

            // DOES NOT WORK: we need to tel the compiler what type of delegate to create
            //CallDelegate(s => Console.WriteLine(s));  // Expression lambda            
        }
        private void CallDelegate(Delegate del)
        {
            del.DynamicInvoke(new object[] { "Hello World 31" });
        }
    }

}

One thought on “Code Listing for ‘Delegate Syntax in C# for Beginners’

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s