c# – Delegates

What if you want the output of one method, to be treated as an input parameter for another method? i.e. you want to do something similar to linux bash piping in the world of c#, but instead of piping from one command, to another, you are piping from one method to another.

Here is an example


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelegateDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // Step 5
            // Here we create an instance of the 
            // Mediatester class, using it's default constructor class.
            // We use this object to access the RunTest method
            // later on. 
            MediaTester ObjectContainingDelegate = new MediaTester();

            // Step 6
            // Here we create ordinary instances
            // of the MP3Player and MP4Player 
            // classes
            MP3Player mp3 = new MP3Player();

            // Step 7
            // We now want to create a reference instance
            // to this object's, PlayMP3File() method,
            // in the form of a delegate:
            MediaTester.TestMedia mp3Delegate = new MediaTester.TestMedia(mp3.PlayMP3File);
            // This syntax is a bit unusual because it is similar to the syntax 
            // you use to create an instance of a class, but in this case 
            // you use it to create a delegate.
            // we use this syntax because we need to tell c# where the delegate is located, so that it can find out
            // it's requirement (i.e. what behaviours matching methods needs to have, e.g. output parameter of integer)
            // as well as the actual object and it's method that we want to reference. 



            // Step 8
            // Now we do the same thing for the 
            // MP4Player class:
            MP4Player mp4 = new MP4Player();
            MediaTester.TestMedia mp4Delegate = new MediaTester.TestMedia(mp4.PlayMP4File);
            
            
            // step 9
            // Here the RunTest method requires a delegate as a input parameter,
            // when it calls on the delegate, the delgate in turn runs the method
            // against it's object, and retrieves the parameter output, which it
            // in turn passes into the RunTest as an input parameter. 
            // After which the RunTest method starts it's execution. 
            ObjectContainingDelegate.RunTest(mp3Delegate); // This line executes "mp3.PlayMP3File()" as part of it's execution. 
            ObjectContainingDelegate.RunTest(mp4Delegate); // This line executes "mp4.PlayMP4File()" as part of it's execution. 

        }
    }

    public class MediaTester
    {
        // Step 1
        // Here we created a delegate called "TestMedia".
        // This delegate can act as delegate for to pipe  
        // any methods that requires no-input but gives out an 
        // integer output parameter. 
        public delegate int TestMedia();

        // Step 2
        // Here we create a method, that accepts an input 
        // parameter in the form of a "TestMedia" delegate. 
        public void RunTest(TestMedia testDelegate)
        {
            // Her we capture the output of the delegate into 
            // an integer variable. This should work since,
            // we defined that the TestMedia is a reference 
            // for any methods that gives an integer output. 
            int result = testDelegate();
            if (result == 0)
            {
                Console.WriteLine("Works!");
            }
            else
            {
                Console.WriteLine("Failed.");
            }
        }
    }

    // // Step 3
    // This is an ordinary class the consists 1 method called PlayMP3File,
    // which happens to fit the input/output parameter requirements of the  
    // "TestMedia" delegate
    class MP3Player
    {
        public int PlayMP3File()
        {
            Console.WriteLine("Playing MP3 file...");
            return 0;
        }

    }


    // Step 4
    // This is an ordinary class the consists 1 method called PlayMP4File,
    // which happens to fit the input/output parameter requirements of the  
    // "TestMedia" delegate 
    class MP4Player
    {
        public int PlayMP4File()
        {
            Console.WriteLine("Playing MP4 file...");
            return 1;
        }

    }


}


This outputs:

A delegate essentially act’s as a placeholder for a method that matches it’s reguirements. See:

http://stackoverflow.com/questions/2019402/when-why-to-use-delegates

http://stackoverflow.com/questions/31497/where-do-i-use-delegates (contains a good analogy of the president of the united states)