Generic Delegate

.Generic Delegate


Generic Delegate Program Output

.Generic Delegate

"A C# program to illustrate a custom generic delegate which has type parameters so it can work with any data type."

Generics provide a higher level of reusability for delegates. This program creates a generic delegate which is then used for both double and string data types. This is contrasted with non-generic delegates where the same capability requires one delegate for the double type and another delegate for the string type. The delegates are implemented with lambda expressions. The following C# features are used in the sample code:

  1. delegate - a type that represents references to methods with a particular parameter list and return typ.e
  2. generic delegate - A delegate can define its own type parameters.
  3. lambda expressions - are anonymous functions that can be used to create delegates or expression tree types.

    Generic Delegate

    namespace DelegateGeneric
    {
        class Program
        {
            // TheDoubleDelegate can only be used with double types
            delegate double TheDoubleDelegate(double x, double y);

            // TheStringDelegate can only be used with string types
            delegate string TheStringDelegate(string x, string y);

            // TheGenericDelegate can be used with ANY TYPE
            delegate TResult TheGenericDelegate<in T1, in T2, out TResult>(T1 x, T2 y);

            static void Header()
            {
                System.Console.WriteLine("*******************************************************");
                System.Console.WriteLine("***    Generic Delegate: Supports all data types    ***");
                System.Console.WriteLine("*******************************************************\n");
            }

            static void Main()
            {
                double arg1d = 5.0;
                double arg2d = 4.0;
                string arg1s = "K";
                string arg2s = "H";

                Header();

                // Use "TheDoubleDelegate" to create delegate for DOUBLE type add
                System.Console.WriteLine("---   Use TheDoubleDelegate for DOUBLE data types   ---\n");
                TheDoubleDelegate myDoubleDelegate = (x, y) => { return x + y; };
                System.Console.WriteLine("{0:N} + {1:N} = {2:N}", arg1d, arg2d, myDoubleDelegate(arg1d, arg2d)); // Prints: 5.0 + 4.0 = 9.0

                // Use "TheStringDelegate" to create delegate for STRING type add
                System.Console.WriteLine("\n---   Use TheStringDelegate for STRING data types   ---\n");
                TheStringDelegate myStringDelegate = (x, y) => { return x + y; };
                System.Console.WriteLine("{0:N} + {1:N} = {2:N}", arg1s, arg2s, myStringDelegate(arg1s, arg2s)); // Prints: K + H = KH

                /****************************************************************
                 * Use Generic Delegate (TheGenericDelegate) for any data types *
                 ****************************************************************/
                System.Console.WriteLine("\n--- Use Generic Delegate for both DOUBLE and STRING ---\n");

                // Use "TheGenericDelegate" to create delegates for both DOUBLE and STRING type adds
                TheGenericDelegate<double, double, double> myGenericDoubleDelegate = (x, y) => { return x + y; };
                System.Console.WriteLine("{0:N} + {1:N} = {2:N}", arg1d, arg2d, myGenericDoubleDelegate(arg1d, arg2d)); // Prints: 5.0 + 4.0 = 9.0

                TheGenericDelegate<string, string, string> myGenericStringDelegate = (x1, y1) => { return x1 + y1; };
                System.Console.WriteLine("{0} + {1} = {2}\n", arg1s, arg2s, myGenericStringDelegate(arg1s, arg2s)); // Prints: K + H = KH
            }
        }
    }