Steveluo’s Blog

Just another WordPress.com weblog

Archive for January, 2009

Back to Basics

Posted by steveluo on January 18, 2009

C#: Back to basics 
1. Delegates( means hand over)
   C# introduced a keyword called delegate for utilizing such things as function pointers and call backs. 
   Delegates are interfaces to pass functionality from one object to another object

My understanding is that delegate is  function pointer in C# implementation:   using the referense of the wrap-up object which contain that function only. so declartion use  hybrid class and method defination.
Delegates can be used for a number of general purposes , including using them as callback methods, defining static methods, and using them to define events.

Interesting facts about delegates: (src)

  • A delegate represents a class.            [should say ‘interface type’  class, the obj should have same signature]
  • A delegate is type-safe.
  • You can combine multiple delegates into a single delegate.
  • You can use delegates both for static and instance methods.
  • You can define delegates inside or outside of classes.
  • You can use delegates in asynchronous-style programming.
  • Delegates are often used in event-based programming, such as publish/subscribe.
  example  
 
using System;
namespace DelegatesSample
{
        // Define a delegate. class definition
        public delegate bool SampleDelegate(string name);     
       class SampleDelegateDriver
      {
             // A delegate variable declaration
             private SampleDelegate m_sampleDelegate;           
         // You need this function to construct your delegate object
           private bool log(string text)
          {
                  Console.WriteLine(text);
                  return true;
           }          
           public void start()
           {
                  Console.WriteLine(“Testing a sample delegate”);                 
                  // Instantiating a simple delegate
                   m_sampleDelegate = new SampleDelegate(log);                  // Calling a simple delegate
                 bool returnCode = m_sampleDelegate(“A simple delegate call”);                 // Combining delegates
                 SampleDelegate d1 = new SampleDelegate(log);
                 SampleDelegate d2 = new SampleDelegate(log);
                 SampleDelegate compositeDelegate =
                                     (SampleDelegate)Delegate.Combine(d1, d2);                  //calling a composite delegate
                  returnCode =
                              compositeDelegate(“Sample composite delegate”);

                   // operator overloading
                  compositeDelegate = d1 + d2;
                  returnCode =
                              compositeDelegate(“Composite delegate,” +
                                                                        “using the + operator”);

                   // you can also remove delegates
                   // delegates are immutable
                  SampleDelegate resultingDelegate =
                     (SampleDelegate)Delegate.Remove(compositeDelegate, d2);
        
                   compositeDelegate(“Composite delegate” + ” after removing one of them”);
                   resultingDelegate(“Resulting delegate” +  ” after removing one of them”);

                   //target of a static method
                   if (m_sampleDelegate.Target == null)
                  {
                         log(“This delegate is pointing to a static method”);
                  }
     
                   // target of an instance method
                   log(“Casting the target to its object type”);
                  SampleDelegateDriver sdd
                                      = (SampleDelegateDriver)m_sampleDelegate.Target;

                  // Enquire targets type name
                 log(“Name of the class that is ” + “implementing the sample delegate: ”
                                   + m_sampleDelegate.Target.GetType().FullName);

                  // Finally see if the ToString method
                 // of your class is called
                 // when invoked on the target instance

                 Console.WriteLine(“TOSTR:” +
                        m_sampleDelegate.Target.ToString());

                  // walking through the delegate list
                  log(“Testing GetInvocation list”);

                   compositeDelegate = d1 + d2;

                   int i=0;
                   foreach(Delegate x in
                              compositeDelegate.GetInvocationList())
                  {
                            log(“delegate ” + i + x.Method.ToString());
                             i++;
                  }
           }

            // Method to test the target property of a delegate
           override public string ToString()
          {
                 return “ToString called”;
          }

          static void Main(string[] args)
          {
                 SampleDelegateDriver sdd =
                             new SampleDelegateDriver();
                 sdd.start();
           }

 

 

 

 

 

 

 namespace SimpleEvent
{
    /* ========= Publisher of the Event ============== */
    public class MyClass
    {
        // Define a delegate named LogHandler, which will encapsulate
        // any method that takes a string as the parameter and returns no value

        public delegate void LogHandler(string message);
 
       
// Define an Event based on the above Delegate

       
public event LogHandler Log;
 

        // Instead of having the Process() function take a delegate
        // as a parameter, we’ve declared a Log event. Call the Event,
        // using the OnXXXX Method, where XXXX is the name of the Event.

        public void Process()
        {
            OnLog(“Process() begin”);
            OnLog
(“Process() end”);
        }
 
        // By Default, create an OnXXXX Method, to call the Event
        protected void OnLog(string message)
        {
            if (Log != null)
            {
                Log(message);
            }
        }

    }
  public class TestApplication
    {
        static void Logger(string s)
        {
            Console.WriteLine(s);
        }
 
        static void Main(string[] args)
        {
            FileLogger fl = new FileLogger(“process.log”);
            MyClass myClass = new MyClass();
 
            // Subscribe the Functions Logger and fl.Logger
            myClass.Log += new MyClass.LogHandler(Logger);
    
            // The Event will now be triggered in the Process() Method
            myClass.Process();

 
            fl.Close();
        }
   
     

 

 

 

 

 

 

 

 

 

 

 

 

   public delegate bool SampleDelegate(String name);
   
C# compiler generates a class called  SampleDelegate in next column!  
    The Invoke() method has the same signature as our delegate declaration
 
public class SampleDelegate : System.MulticastDelegate
 {
         public SampleDelegate(object target, int method); //constructor 
    public virtual void Invoke(string name);
    public virtual IAsyncResult BeginInvoke(string name,
AsyncCallback callback, object obj);
    public virtual void EndInvoke(IAsyncResult result);

 }

2)  Delegate with event
    The basic foundation behind C# eevnt model is the publisher and subscribers.
     publisher:    —  publish an event 
           1) declare a Delegate 
           2) declare an event based on the  Delegate   
           3)  fire the event
    subscribers:
           subscribed event
          event handler
 

 See MSDN’s Handling and Raising Events

    Button Class  (event in GUI)     from 3.0 Spec 
creates two Button instances and attaches event handlers to the Click events.

 Field-like events

public delegate void EventHandler(object sender, EventArgs e);

public class Button: Control
{
      public event EventHandler Click;
}

public class LoginDialog: Form
{
     Button OkButton;
     Button CancelButton;

     public LoginDialog()
     {
           OkButton = new Button(…);
           OkButton.Click += new EventHandler(OkButtonClick);
           CancelButton = new Button(…);
           CancelButton.Click += new EventHandler(CancelButtonClick);
     }

     void OkButtonClick(object sender, EventArgs e) {
           // Handle OkButton.Click event
     }

     void CancelButtonClick(object sender, EventArgs e) {
           // Handle CancelButton.Click event
     }
}

public delegate void EventHandler(object sender, EventArgs e);

public class Button: Control
{
     //Click is used as a field within the Button class
     public event EventHandler Click;

     //The OnClick method “raises” the Click event
    // which equivalent to invoking the delegate represented by the event

     protected void OnClick(EventArgs e) {
           if (Click != null)
                   Click(this, e);
     }

     public void Reset() {
           Click = null;
     }
}

class X
{
     public event D Ev;
}

Which is compiled to :

class X
{
     private D __Ev;  // field to hold the delegate

     public event D Ev {
           add {
                lock(this) { __Ev = __Ev + value; }
           }

           remove {
                lock(this) { __Ev = __Ev – value; }
           }
     }
}

Posted in C# | Tagged: | 1 Comment »