58

I've read two books, tons of examples. They still make next to no sense to me. I could probably write some code that uses delegates, but I have no idea why. Am I the only one with this problem, or am I just an idiot? If anyone can actually explain to me when, where, and why I would actually use a delegate, I'll love you forever.

Kin
  • 1,407
  • 20
  • 24
  • 3
    do you understand function pointers and why you'd use them in C++? – Matt Ellen Apr 20 '10 at 21:08
  • No I do not, would learning that help to understand delegates? – Kin Apr 20 '10 at 21:10
  • 5
    @Kin, if you understood function pointers you would think that delegates were a godsend. –  Apr 20 '10 at 21:15
  • Will I need to learn C++ to understand them (reading a book). – Kin Apr 20 '10 at 21:17
  • 2
    @Kin: no. You can learn it without C++. Having done it in C++ would give you a leg up, but it would be silly to try to learn it in C++ just to do the same thing in C#. – Beska Apr 20 '10 at 21:22
  • 1
    Knowing C/C++/Java helps when starting with C#, because the syntax is familiar. They all have some way of passing callbacks, but none as elegant as the delegate, so don't bother reading about them. –  Apr 20 '10 at 21:24
  • Trust me, keep trying. Delegates, anonymous delegates, LINQ etc are what make C# amazing. – Callum Rogers Apr 20 '10 at 21:40
  • It is not going to be easy to accept a single answer here. – Kin Apr 20 '10 at 21:53
  • @Kin I totally and completely empathise with you. i have spent a good couple of hours and still do not understand WHY one will need to use a delegate. and everyone else says Oh it's just: "function pointer; call back, etc" but i still don't get WHY? Are you able to provide a good explanation given your experience now? – BenKoshy Feb 14 '16 at 21:35
  • It's because of recursive thinking. Languages that expect people to think recursively are hard to wrap your head because your mind isn't wired that way. I ended up with a disease that attacks parts of my brain, and since then much of programming no longer makes sense. Unfortunate. This inequality in the world will never go away. Capable or incapable though sounding harsh, is the truth of it. But it'd be nice if those blessed with the high-level thinking didn't go out of their way to kick those who don't in the face every time. Not saying give up but I AM saying it's not your fault. – osirisgothra Feb 08 '23 at 17:39

6 Answers6

18

Delegates are just a way to pass around a function in a variable.

You pass a delegated function to do a callback. Such as when doing asynchronous IO, you pass a delegated function (a function you have written with the delegate parameter) that will be called when the data has been read off the disk.

Byron Whitlock
  • 52,691
  • 28
  • 123
  • 168
  • 1
    That actually makes more sense then I have seen so far, thanks. – Kin Apr 20 '10 at 21:16
  • 6
    In my opinion, some of the initial learning curve stems from the delegate syntax. When you first start off, it feels like a whole lot of ceremony. To make matters worse, it can feel like everyone else but you thinks it's all so simple. (Not criticizing the syntax... just recalling my learning experience.) – Larsenal Apr 20 '10 at 21:36
  • 2
    It does feel like that. I've seen examples that tries to explain them, has examples, and proceeds to say "Now isn't that great?", while I was just scratching my head. – Kin Apr 20 '10 at 21:42
  • 3
    This is how I think of a delegate. It's a variable containing a method. You can have a collection of them, you can cast them, you can define them... etc – Chuck Conway Apr 20 '10 at 21:49
  • Thanks Byron. I needed that. – Justin Russo Feb 25 '14 at 19:35
  • 1
    An example to this would be great :) – Shukhrat Raimov Jan 25 '16 at 23:06
  • 1
    @Byron any chance you could elaborate on what a call back is? i've read other answers on whtat it is but did not clearly understand. – BenKoshy Feb 14 '16 at 21:26
4

As other people have mentioned delegates are handy for callbacks. They're useful for a whole load of other things too. For example in a game I've been working on recently bullets do different things when they hit (some do damage, some actually increase the health of the person they hit, some do no damage but poison the target and so on). The classical OOP way to do this would be a base bullet class and a load of subclasses

Bullet
    DamageBullet
    HealBullet
    PoisonBullet
    DoSomethingElseBullet
    PoisonAndThenHealBullet
    FooAndBarBullet
    ....

With this pattern, I have to define a new subclass every time I want some new behavior in a bullet, which is a mess and leads to a lot of duplicated code. Instead I solved it with delegates. A bullet has an OnHit delegate, which is called when the bullet hits an object, and of course I can make that delegate anything I like. So now I can create bullets like this

new Bullet(DamageDelegate)

Which obviously is a much nicer way of doing things.

In functional languages, you tend to see a lot more of this kind of thing.

Martin
  • 12,469
  • 13
  • 64
  • 128
3

A delegate is a simple container that knows where in the machine's memory a specific method is located.

All delegates have an Invoke(...) method, thus when someone has a delegate, he can actually execute it, without really having to know or bother what that method actually does.

This is especially helpful for decoupling stuff. GUI frameworks wouldn't be possible without that concept, because a Button simply can't know anything about your program you're going to use it in, so it can't call your methods by itself whenever it is clicked. Instead, you must tell it which methods it should call when it is clicked.

I guess you're familiar with events and you do use them regularly. An event field is actually a list of such delegates (also called a multi-cast delegate). Maybe things will become clearer when we look at how we could "simulate" events in C# if it didn't have the event keyword, but only (non-multicast) delegates:

public class Button : Rectangle
{
    private List<Delegate> _delegatesToNotifyForClick = new List<Delegate>();

    public void PleaseNotifyMeWhenClicked(Delegate d)
    {
        this._delegatesToNotifyForClick.Add(d);
    }

    // ...

    protected void GuiEngineToldMeSomeoneClickedMouseButtonInsideOfMyRectangle()
    {
        foreach (Delegate d in this._delegatesToNotifyForClick)
        {
            d.Invoke(this, this._someArgument);
        }
    }
}

// Then use that button in your form

public class MyForm : Form
{
    public MyForm()
    {
        Button myButton = new Button();
        myButton.PleaseNotifyMeWhenClicked(new Delegate(this.ShowMessage));
    }

    private void ShowMessage()
    {
        MessageBox.Show("I know that the button was clicked! :))))");
    }
 }

Hope I could help a little. ;-)

herzmeister
  • 11,101
  • 2
  • 41
  • 51
2

Maybe this helps:

  • A delegate is a type (defining a method signature)
  • A delegate instance is a reference to a method (AKA function pointer)
  • A callback is a parameter of a delegate-type
  • An event is a (kind of) property of a delegate-type

The purpose of delegates is that you can have variables/fields/parameters/properties(events) that 'hold' a function. That lets you store/pass a specific function you select runtime. Without it, every function call has to be fixed at compile time.

The syntax involving delegates (or events) can be a bit daunting at first, this has 2 reasons:

  1. simple pointer-to-functions like in C/C++ would not be type-safe, in .NET the compiler actually generates a class around it, and then tries to hide that as much as possible.

  2. delegates are the corner-stone of LINQ, and there is a steep evolution from the specify-everything in C#1 through anonymous methods (C#2) to lambdas (C#3).

Just get acquainted with 1 or 2 standard patterns.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
H H
  • 263,252
  • 30
  • 330
  • 514
  • That does help a bit, I've never seen an event described as a property. – Kin Apr 20 '10 at 21:12
  • @Kin, We ususally see the short notation of an event. The full notation uses add/remove instead of the get/set accessors of a normal property, see http://msdn.microsoft.com/en-us/library/cc713642.aspx – H H Apr 20 '10 at 21:15
2

Come on Guys! All of you successfully complicated the DELEGATES :)!

I will try to leave a hint here : i understood delegates once I realized jquery ajax calls in Javascript. for ex: ajax.send(url, data, successcallback, failcallback) is the signature of the function. as you know, it sends data to the server URL, as a response, It might be 200OK or some other error. In case of any such event(success/fail), you want to execute a function. So, this acts like a placeholder of a function, to be able to mention in either success or failure. That placeholder may not be very generic - it might accept a set of parameters and may/may not return value. That declaration of such Placeholder, if done in C# IS CALLED DELEGATE! As javascript functions not strict with number of arguments, you would just see them as GENERIC placeholders...but C# has some STRICT declarations... that boils down to DELEGATE declarations!!

Hope it helps!

HydTechie
  • 797
  • 10
  • 17
0

Delegate is a type safe function pointer, meaning delegate points to a function when you invoke the delegate function the actual function will be invoked. It is mainly used when developing core application framework. When we want to decouple logic then we can use delegate. Ie instead of hand coding logic in a particular method we can pass the delegate to the function and set different function logic inside the delegate function. Delegates adds flexibility to your framework.

Example: how to use it

class Program
{
    public static void Main()
    {
        List<Employee> empList = new List<Employee>() {
           new Employee () {Name = "Test1", Experience = 6 },
           new Employee () {Name = "Test2", Experience = 2 },
          };

        // delegate point to the actual function
        IsPromotable isEligibleToPromote = new IsPromotable(IsEligibleToPromoteEmployee);
        Employee emp = new Employee();

        // pass the delegate to a method where the delegate will be invoked.
        emp.PromoteEmployee(empList, isEligibleToPromote);

        // same can be achieved using lambda empression no need to declare delegate 
        emp.PromoteEmployee(empList, emply => emply.Experience > 2);

        Console.ReadKey();
    }

    // this condition can change at calling end 
    public static bool IsEligibleToPromoteEmployee(Employee emp)
    {
        if (emp.Experience > 5)
            return true;
        else
            return false;
    }
}


public delegate bool IsPromotable(Employee emp);
public class Employee
{
    public string Name { get; set; }
    public int Experience { get; set; }

    // conditions changes it can 5, 6 years to promote
    public void PromoteEmployee(List<Employee> employees, IsPromotable isEligibleToPromote)
    {
        foreach (var employee in employees)
        {
            // invoke actual function
            if (isEligibleToPromote(employee))
            {
                Console.WriteLine("Promoted");
            }
        }
    }
}
zulqadar idrishi
  • 105
  • 1
  • 11
Nayas Subramanian
  • 2,269
  • 21
  • 28