Click here to Skip to main content
15,916,951 members
Please Sign up or sign in to vote.
1.00/5 (4 votes)
See more:
what is the main purpose of delegates in c#?
Posted
Comments
Ankur\m/ 30-Apr-15 6:22am    
Did you try Google search? If not, I strongly recommend giving it a try. You will be amazed by the help it offers you.
Here you go - http://bit.ly/1OHP0D9
Sinisa Hajnal 30-Apr-15 6:33am    
Write exact this question in google and you'll get plenty of forums where such is discussed from MSDN, SO, CP, c-sharpcorner and others.
BillWoodruff 30-Apr-15 8:24am    
The least you can do is to do a search here on CodeProject and read some of the articles here on Delegates.

Basically they specify a method as a type, including signature specification.


I use them all the time. Here are some real world examples:

I have custom web controls. If the control is given a Label then both controls are wrapped together. I can pass Render methods as delegates:

C#
//This is my render method delegate
public delegate void HtmlRenderMethod(HtmlTextWriter writer);

public override void Render(HtmlTextWriter writer){

  if(!string.IsnullOrEmpty(Label)){
     RenderWrapper(base.Render,writer); //method must match signature
  }
  else{
    base.Render(writer);
  }
}

private void RenderWrapper(HtmlRenderMethod method, HtmlTextWriter writer){
    writer.RenderOpenTag("div");
    RenderLabel(writer);
    method(writer); //I can use it just like a method
    writer.RenderCloseTag();
}


My render methods are far more complex that this. For example I have the base ValidatedTextbox that inherits TextBox but I have other controls that inherit from ValidatedTextbox. If I want access to the TextBox Render method without having to go through the ValidatedTextbox render method then I can just save the original method in a protected variable and call it from any ancestor.

I have also started my custom workflow engine. This will operate on a message-to-method basis. I need to know what method handles what kind of message. To do this I create a delegate and create a dictionary<message,method>:

C#
    public delegate Engine.WorkflowResult MessageHandler(IMessage message);
    public class MessageHandlerList : Dictionary<type,>
    {
        public Engine.WorkflowResult TryParse(IMessage message)
        {
            if (!ContainsKey(message.GetType()))
                return WorkflowResult.Wait;
            return this[message.GetType()](message);
        }

        public new bool ContainsKey(Type key)
        {
            return Keys.Any(k => k.GUID == key.GUID);
        }

        public new MessageHandler this[Type key]
        {
            get { return base[Keys.Single(k => k.GUID == key.GUID)]; }
            set { base[Keys.Single(k => k.GUID == key.GUID)] = value; }
        }
    }
...

private MessageHandlerList _messageHandlers {get;set;}

public void Initialize(){
   _messageHandlers = new MessageHandlerList();

   _messageHandlers.Add(ProcessStartMessage,ProcessStartHandle);
   _messageHandlers.Add(ProcessEndMessage,ProcessEndHandle);
 
}

public Engine.WorkflowResult ParseMessage(IMessage message){
    return _messageHandlers.TryParse(message)
}

private Engine.WorkflowResult ProcessStartHandle(IMessage message){
    if(!message.Deserialized)
        message.Deserialize();
    ProcessStartMessage startMessage = (ProcessStartMessage)message;

    //do stuff
}

private Engine.WorkflowResult ProcessEndHandle(IMessage message){
    if(!message.Deserialized)
        message.Deserialize();
    ProcessEndMessage startMessage = (ProcessEndMessage)message;

    //do stuff
}
...



I also use delegates when I wrap transactions on the database. I use a more open delegate so I can get any return type I like, so long as the core delegate returns void:
C#
public delegate void Transaction();

 public static void TransactionWrapper(Transaction transaction)
 {
  var options = new TransactionOptions
  {
   IsolationLevel = IsolationLevel.Snapshot,
   Timeout = TimeSpan.FromSeconds(120)
  };

  using (var scope = new TransactionScope(TransactionScopeOption.Required, options))
  {
   transaction();

   scope.Complete();
  }
 }


...

public List<message> SelectAllDue(DatabaseContext db = null){
  if(db==null)
    db = new DatabaseContext(); 

  List<messages> result = null;

  //inline use of delegate
  TrasactionWrapper(()=>{
    var query = db.Messages;
    query = query.Where(m=>m.Due < DateTime.Now);
    result = query.ToList();    
  }

  return result

}

...</messages></message>



There are many other clever things you can do as well. You can have composite delegate groups even.

Every Lamda expression is technically a delegate

These are a few 'real world' examples, that I have trimmed for simplicity.
 
Share this answer
 
v2
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900