Click here to Skip to main content
15,887,411 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Actually, I want to know about what is a delegate.

I search and read so many articles from the internet and all of them tell that A DELEGATE IS USED TO POINT TO A METHOD.

I need the following questions about delegates.

1. If I Declare a method in a class for eg.
C#
public Class Message
{
   public void Show(string Msg)
   {
    //Todo
   }
}


I want to know what is the basic difference and advantage of calling this method through the object of this class and through a delegate and what is the benefit for that.

If i can call this method like a normal method

Message msg = new Message();
msg.Show("");

public delegate void MsgDelegate(string Msg);

MsgDelegate ObjMsg;

ObjMsg + = Show();
ObjMsg ("");


SO I WANT TO KNOW WHAT IS THE DIFFERENCE FOR THIS TWO CALLING
NORMAL METHOD CALLING AND DELEGATE CALLING.







Regards
Riyas K
Posted
Updated 11-Apr-17 19:37pm
v3

This is not so easy to explain at once. And yes, most of the articles I ever saw are unsatisfactory.
First, you should not mix up delegate types and delegate instances. The relationship between them is very different from relationships between other user-defined types and instances.

A delegate type defined a signature of the method with could serve as a handler method which could be added to an invocation list of a delegate instance, such as
C#
delegate uint StringHandler(string value, int index);

Now, let's define a delegate index:
C#
StringHandler stringHandler;

Now, the question is: what is the type of stringHandler? Is it StringHandler?

It is — surprise! — listen carefully, pay full attention; it is not!

It' is easy to find out, but you can do it only if you add some handler to the instance; before you do, this object is always null. OK, let's do it:
C#
stringHandler = (value, index) => {
   if (value.IsNullOrEmpty)
      return 0;
   else
      return value.Length - index; // no matter what; this is just an example
};


For C# v.2, you cannot use lambda syntax or type inference, so the syntax would be a bit longer:
C#
stringHandler = delegate(string value, int index) { /* ... */ }


Now, you can get a run-time type of the instance:
C#
System.Type delegateInstanceType = stringHandler.GetType();


Examine this type; and you will see that this is a type which has nothing to do with StringHandler. You will find out that this is a… class, derived from System.Delegate. Please see:
http://msdn.microsoft.com/en-us/library/system.delegate.aspx[^].

It has many members, but you will find that it has the member representing its invocation list: GetInvocationList:
http://msdn.microsoft.com/en-us/library/system.delegate.getinvocationlist.aspx[^].

The members of the list are… also delegate instances. Recursion in action? Not exactly. The list has interesting functionality: it is flat. Its member cannot be null, and its member is never multicast.

So, what makes a delegate instance callable? It resembles a method, because it can be invoked via the method Invoke, which calls all the elements of the invocation list. OK, but what makes those methods callable. Essentially, they point to two things: first, this is the address of a method to be called. Second, if the method is the instance (non-static method), a delegate instance should store the reference to the instance of some type to be passes as "this" to the instance method. This is exactly what happens. The handler added with '+=' can come in the form instance.Method or type.Method. In first case, the reference to the instance is passed to the invocation list; the second case is the case of static method, the reference to the instance is not used. When a delegate invocation happens, the stored reference to the instance is passed to a called method as the implicit "this" parameter.

Is the invocation list actually grow when another handler is added. Surprise again: it is not (!). Delegate instances are immutable. When '+=' operator is applied, a brand new delegate instance is created, with longer invocation list. As a result, the variable representing the delegate instance is loosing its referential identity. One reason for such architecture is the improvement in multithreading.

This topic is explained in the section 4.1 of article Dynamic Method Dispatcher[^].

For additional; explanation on static and instance methods, please see my past answer:
What makes static methods accessible?[^].

I guess next question would be on event… To be intrigues a bit, please see this question and my answer:
Since we have multicast delegates, why do we need events?[^].

Basically, delegates is the mechanism to introduce first-class functions in .NET. Please see:
http://en.wikipedia.org/wiki/First-class_function[^].

In particular, delegate instanced can be passed as parameters to other methods which are used to abstract out algorithms. This is one of them major features of functional programming. Please see:
http://en.wikipedia.org/wiki/Functional_programming[^].

—SA
 
Share this answer
 
v4
Comments
Wonde Tadesse 30-Mar-12 19:26pm    
5+. Superb answer
Sergey Alexandrovich Kryukov 30-Mar-12 21:06pm    
Thank you very much, Wonde.
--SA
ProEnggSoft 1-Apr-12 9:00am    
Comprehensive answer. +5
Sergey Alexandrovich Kryukov 1-Apr-12 10:52am    
Thank you.
--SA
For starters, to get a better understanding of delegates, you should read the MSDN documentation[^] on the subject. The examples on this page give a very clear picture of what the delegate is actually there for.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 30-Mar-12 16:51pm    
Unfortunately, there are too many things left unexplained behind this article, and, I guess, all the Microsoft documentation.
If you don't feel so, please look at my answer.
All my statements can be validated experimentally, if you want.
--SA
Maybe this will help.

In the case you are talking about you are sending the message to a MessageBox. The delegate you might define for this is:

public delegage void Msg(string s);


Now you can define some methods that have this signature:

private void MsgBox (string s)
{
  MessageBox.Show (s);
}

private void MsgConsole (string s)
{
  Console.WriteLine (s);
}

private void MsgOutput(string s)
{
  Debug.Print(s)
}

Now in your program you can have a variable that is defined as

private Msg SendToRightOutput;


then in some method you can:

SendToRightOutput(s);


Now you can select where the output goes in one place, and everymethod that uses the SendToRightOutput will automatically send output to the right place. Another nice thing is that you can assign multiple places to send the output. The way you assign a value to the SendToRightOutput variable is:

SendToRightOutput += MsgConsole;

Hopefully this will make it clearer.
 
Share this answer
 

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