Figure 1

Figure 1 DelegateDemo.cs
using System;
using System.WinForms;	// In beta2: System.Windows.Forms
using 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;
   }

   // Define a Feedback type 
   // (NOTE: this type is nested within the Set class)
   public delegate void Feedback(
      Object value, Int32 item, Int32 numItems);

   public void ProcessItems(Feedback feedback) {
      for (Int32 item = 0; item < items.Length; item++) {
         if (feedback != null) {
            // If any callbacks are specified, call them
            feedback(items[item], item + 1, items.Length);
         }
      }
   }
}


class App {
   [STAThreadAttribute]
   static void Main() {
      StaticCallbacks();
      InstanceCallbacks();
   }


   static void StaticCallbacks() {
      // Create a set with 5 items in it
      Set setOfItems = new Set(5);

      // Process the items, give no feedback
      setOfItems.ProcessItems(null);
      Console.WriteLine();

      // Process the items, give feedback to console
      setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToConsole));
      Console.WriteLine();

      // Process the items, give feedback to a message box
      setOfItems.ProcessItems(new Set.Feedback(App.FeedbackToMsgBox));
      Console.WriteLine();

      // Process the items, give feedback to the 
      // console AND a message box
      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 with 5 items in it
      Set setOfItems = new Set(5);

      // Process the items, give feedback to a 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();
   }
}
Figure 2 Feedback Class
public class Feedback : System.MulticastDelegate {
   // Constructor
   public Feedback(Object target, Int32 methodPtr);

   // Method with same prototype as specified by the source code
   public void virtual Invoke(
      Object value, Int32 item, Int32 numItems);

   // Methods allowing the callback to be called asynchronously
   // I'll discuss these methods in a future article
   public virtual IAsyncResult BeginInvoke(
      Object value, Int32 item, Int32 numItems, 
      AsyncCallback callback, Object object);
   public virtual void EndInvoke(IAsyncResult result);
}
Figure 3 Verifying Compiler Class Generation

Figure 3 Verifying Compiler Class Generation
Figure 4 Private Fields for Delegate Types
Field
Type
Description
_target
System.Object
Refers to the object that should be operated upon when the callback method is called. This is used for instance method callbacks
_methodPtr
System.Int32
An internal integer that the CLR uses to identify the method that is to be called back
_prev
System.MulticastDelegate
Refers to another delegate object. This is usually null