Callback Function The callback function is indeed one of the most useful programming mechanisms so far. The qsort function in C Runtime uses the callback function to sort array elements. In Windows, the callback function is also a window process, hook process, asynchronous process call, and currently required by the Microsoft. NET Framework. The callback method is used throughout the entire callback process. People can register callback methods to receive loading/unloading notifications, unhandled exception notifications, database/window status modification notifications, file system modification notifications, menu item selection, and completed Asynchronous Operation notifications, filter a group of entries. In C/C ++, the address of a function is the memory address. This address does not contain any additional information, such as the number of parameters, parameter types, return value types, and call specifications of the function. In short, C/C ++ callback functions are not of type security. In the. NET Framework, callback functions are reused in the same way as Windows uncontrolled programming. The difference is that the. NET Framework provides a type security mechanism called delegation. Let's first study the delegate statement. The following code demonstrates how to declare, create, and use delegates: |
// Using System; using System. winForms; // In beta2, the value is System. windows. formsusing System. IO; class Set {private Object [] items; public Set (Int32 numItems) {items = new Object [numItems]; for (Int32 I = 0; I <numItems; I ++) items [I] = I;} // defines Feedback and its type is delegate // (Note: This type is nested in the Set class) public delegate void Feedback (Object value, Int32 item, Int32 numItems); public void ProcessItems (Feedback feedbac K) {for Int32 (item = 0; item <items. Length; item ++) {if (feedback! = Null) {// call them feedback (items [item], item + 1, items. length) ;}}} class App {[STAThreadAttribute] static void Main () {StaticCallbacks (); InstanceCallbacks ();} static void StaticCallbacks () {// create a Set object, five of which are setOfItems = new Set (5); // process the project, feedback = null setOfItems. processItems (null); Console. writeLine (); // process the project, feedback = Console setOfItems. processItems (new Set. feedback (App. feedbackToConsole); Console. writeLine (); // processing project, feedback = MsgBox setOfItems. processItems (new Set. feedback (App. feedbackToMsgBox); Console. writeLine (); // process the project, feedback = console AND MsgBox Set. feedback fb = null; fb + = new Set. feedback (App. feedbackToConsole); fb + = new Set. feedback (App. feedbackToMsgBox); setOfItems. processItems (fb); Console. writeLine ();} static void FeedbackToConsole (Object value, Int32 item, Int32 numItems) {Console. writeLine ("Processing item {0} of {1 }:{ 2 }. ", item, numItems, value);} static void FeedbackToMsgBox (Object value, Int32 item, Int32 numItems) {MessageBox. show (String. format ("Processing item {0} of {1 }:{ 2 }. ", item, numItems, value);} static void InstanceCallbacks () {// create a Set object, with five elements Set setOfItems = new Set (5 ); // process the project, feedback = File App appobj = new App (); setOfItems. processItems (new Set. feedback (appobj. feedbackToFile); Console. writeLine ();} void FeedbackToFile (Object value, Int32 item, Int32 numItems) {StreamWriter sw = new StreamWriter ("Status", true); sw. writeLine ("Processing item {0} of {1 }:{ 2 }. ", item, numItems, value); sw. close ();}}// |
Pay attention to the Set class at the top of the Code. Suppose this class contains a group of projects that will be processed separately. When you create a Set object, pass the number of items it wants to manipulate to its constructor. Then the constructor creates an object (Objects) array and initializes each integer value. In addition, the Set class defines a Public Delegate, which indicates the signature of a callback function. In this example, assign Feedback to determine a method with three parameters (the first parameter is Object, the second and third parameters are of the Int32 type) and return void. In a sense, delegates are very similar to the type definition (typedef) that represents a function address in C/C ++ ). In addition, the Set class defines a public method: ProcessItems. This method has a parameter feedback-a reference to the delegate Feedback object. ProcessItems iterates through all the array elements and calls a callback method for each element (the callback method is specified by the feedback variable). This callback method is passed, in this way, the project value, the number of projects, and the number of elements in the array are processed in different ways. We can see that the callback method can process every project in any way it chooses. |
Use delegates to call static methods The StaticCallbacks method demonstrates different callback delegation methods. This method first constructs a Set object and tells it to create an array with five object elements. Then ProcessItems is called. In the first call, its feedback parameter is null. ProcessItems presents a method that implements some action for the project operated by each Set. In the first example, because the feedback parameter is null, no callback method is called when processing each project. In the second example, a new Set. FeedBack delegate object is created. This delegate object is a method package that allows indirect call of methods through this package. For the FeedBack constructor of the type, the method name (App. FeedBackConsole) is passed as a parameter of the constructor; this indicates that the method is encapsulated. Then, the reference returned from the new operator is passed to ProcessItems. Now, when ProcessItems is executed, it calls the FeedbackToConsole method of the App type to process each project in the set. The FeedbackToConsole simply outputs a string to the console, indicating the project to be processed and the value of the project. The Third and Second examples are basically the same. The only difference is that the Feedback delegate object wraps another method: App. FeedbackToMsgBox. This method creates a string that indicates the project to be processed and the project value. Then, the string is displayed in an information box. The fourth example is static call. The last example demonstrates how to link delegates together to form a chain. In this example, first create a Feedback to delegate the object's reference variable fb and initialize it to null. This variable points to the delegate linked list header. The Null value indicates that there are no nodes in the linked list. Then, construct the Feedback delegate object, which wraps the call to the FeedbackToConsole method of the App. In C #, The + = Operator is used to add objects to the linked list referenced by fb. Fb points to the head of the linked list. Finally, construct another Feedback delegate object, which wraps the call to the App FeedbackToMsgBox method. The + = Operator in C # is used again to add objects to the linked list referenced by fb, And the fb is updated by the new linked list header. Now, when ProcessItems is executed, the header pointer assigned by Feedback to the chain table is passed to it. In ProcessItems, the code line that calls the callback method actually terminates calling all the callback Methods encapsulated by Delegate objects in the linked list. That is to say, FeedbackToConsole is called for each project to be iterated, and FeedbackToMsgBox is immediately called. In subsequent articles, I will discuss in detail the handling mechanism of the delegate chain. It is very important that everything in this example is type-safe. For example, when constructing a Feedback delegate object, the compiler ensures that the FeedbackToConsole and FeedbackToMsgBox methods of the App have the exact prototype, as defined by Feedback delegation. Both methods must have three parameters (Object, Int32, and Int32), and both methods must have the same return type (void ). If The method prototype does not match, The compiler sends The following error message: "error CS0123: The signature of method App. FeedbackToMsgBox () does not match this delegate Type ." -- The signature of the App. FeedbackToMsgBox () method does not match the delegate type. |
Call instance method We have discussed how to use delegates to call static methods. However, delegates can also be used to call instance methods of specific objects. When calling an instance method, delegate the instance of the object that needs to be known to be operated by the method. To understand the callback mechanism of the instance method, let's look back at the InstanceCallbacks method in the previous code. This code is very similar to static methods. Note that after the Set object is created, the App object is created. This App object is only created for the purpose of the example. When a new Feedback delegate object is created, its construction is complete and uploaded to appobj. FeedbackToFile. This will cause this delegate to wrap references to the FeedbackToFile method. FeedbackToFile is an instance method (non-static ). When this instance method is called, the object referenced by appobj is operated (as a hidden passing parameter ). The FeedbackToFile method works a bit like FeedbackToConsole and FeedbackToMsgBox. |