What is a Delegate?
//Define a delegate type with no return value and no parameters. delegate void PrintFunction(); class Test { public void Print1() { Console.WriteLine("Print1 - instance"); } public static void Print2() { Console.WriteLine("Print2 - static"); } } namespace ConsoleApplication5 { class Program { static void Main(string[] args) { Test t = new Test(); //Create a test class instance. PrintFunction pf; //Create a null delegate. pf = t.Print1; //Instantiate and initialize the delegate. //Add three more methods to the delegate. /* In reality, because delegates are immuateble, the resulting delegate with four methods in its invocation list * is an entirely new delegate pointed at by the variable. What is actually happening, of coures, is that when the * += operator is used, a new delegate is created, with an invocation list that is combination of the delegate on * left plus the method listed on the right. This new delegate is then assigned to the pf variable. */ pf += Test.Print2; pf += t.Print1; pf += Test.Print2; //The delegate now contains four methods. if (null != pf) //Make sure the delegate isn't null. pf(); //Invoke the delegate. else Console.WriteLine("Delegate is empty!"); //Remove the method Print1 from the delegate. /*If there are multiple entries for a method in the invacation list, the -= operator stats searching at the bottom *of the list and removes the first instance of the matching method it finds. *Attempting to delete a method that is not in the delegate has no effect. *Attempting to invoke an empty delegate throws an exception. *You can check whether a delegate's invocation list is empty by comparing the delegation to null. *If the invocation list is empty, the delegate is null. */ pf -= t.Print1; if (null != pf) pf(); else Console.WriteLine("Delegate is empty!"); //Combining Delegates /* Notice that the operand delegates remain unchanged.*/ PrintFunction mypf1,mypf2; mypf1 = Test.Print2; mypf2 = pf + mypf1; //Has combined invocation list. if (null != pf) mypf2(); else Console.WriteLine("Delegate is empty!"); } } }
A delegate is a user-defined type, like a class. But whereas a class represents a collection of data, a delegate keeps track of one or more methods. You use a delegate by doing the following.
- Declare a new delegate type with a particular signature and return type. A delegate declaration looks like a method declaratcion, except that it doesn't have an implementation block.
- Declare a delegate variable of the new delegate type.
- Create an object of the delegate type, and assign it to the delegate variable. The new delegate object includes a reference to a method with the same signature as defined in the first step.
- Add addtional methods into the delegate object. These methods must have the same signature and return type defined in the first step.
- Throughout your code you can then invoke the delegate, just as if it were a method. When you invoke the delegate, each of the methods it contains is exectued.