1

I am trying to understand "callback pattern". Every answer says that this is done with delegates (which I know them). But the codes on the answers are something like that:

public delegate void Callback(string result);

public void Test()
{
    CallBack callback = CallbackFunction; 
    DoWork(callback);
}

public void DoWork(CallBack callback)
{
    callback("Hello world");
}

public void CallbackFunction(string result)
{
    Console.WriteLine(result);
}

I really don't understand, why we need delegate for this? We can do this in this way too?

public void Test()
{
    DoWork();
}

public void DoWork()
{
    CallbackFunction("Hello world");
}

public void CallbackFunction(string result)
{
    Console.WriteLine(result);
}

Besides that, for example in Java, a callback means a real "return" to the main program's "particular function" after an event. But when we use delegates, isn't this just calling another method?

How can we make a callback that finally calls an OnFail() method on fail, and OnSuccess() method on success. I am really confused. Can somebody help me to understand this?

Servy
  • 202,030
  • 26
  • 332
  • 449
Zapdos
  • 617
  • 1
  • 6
  • 23
  • delegate is a template for function which can be used in current context `DoWork` in your case. Easiest example is event handlers. – Fabio Dec 02 '16 at 17:16
  • I know but why should I use it? Especially for callback? It is not doing a callback? Besides, what is the difference between calling a method with its name and calling a delegate which calls the methods name? – Zapdos Dec 02 '16 at 17:18
  • There are already a few answers covering why you would use delegates. http://stackoverflow.com/questions/3567478/delegates-why – Equalsk Dec 02 '16 at 17:18
  • @Equalsk I have already looked that post and similar 10+ posts. They are all saying we use delegates for this. I am asking why? It is not presenting a proper callback functionality. I am sure it presents though. But I can not understand it. – Zapdos Dec 02 '16 at 17:20
  • _I know but why should I use it?_ - Because you want compile time exception if wrong method was passed to as `callback` -not in runtime – Fabio Dec 02 '16 at 17:20
  • @Fabio The second code sample is doing the same thing with the first. Second one gives a compile time error too if wrong method was called? – Zapdos Dec 02 '16 at 17:25
  • @Zapdos - no, in second I can write another method inside `DoWork` with two parameters and it will compile - but not work correctly. As I said - best example is event. Your class have an event how you will inform consumers of the class which signature can be used for eventhandlers – Fabio Dec 02 '16 at 17:28
  • @Fabio In first code, I can subscribe another method to the delegate which can compile but not work correctly too? – Zapdos Dec 02 '16 at 17:32
  • 1
    Your second example is not dynamic. What if you want `DoWork` to call a different method? That's the idea of events, the coder doesn't know what method you want them to call, but they tell you what the signature of the method should be with a delegate. I believe this is handled in Java with interfaces and anonymous classes. – juharr Dec 02 '16 at 17:38
  • @juharr A delegate calls methods which are subscribed to it,am I wrong? If we want our delegate to call another method, we should subscribe it. If I want to call another method like in second one, I have to add it too. What is the difference between subscribing my other method to delegate and calling another method? – Zapdos Dec 02 '16 at 17:44
  • @Zapdos I'm not sure I understand exactly what you're asking. When you "subscribe" to an event you are actually adding the method to a multi-cast delegate which allows the event to call all the subscribed methods. The purpose of the delegate is to set the signature of the methods that can be subscribed. But as you see in your code you can also pass a method as a delegate to another method where it can be used as a callback. – juharr Dec 02 '16 at 17:48
  • @juharr I think I should change my question into this: How to return to a function in main class which a "callback" does after its work, with using delegates. – Zapdos Dec 02 '16 at 17:52
  • There is no need for a delegate here. Delegates are one of the bigger abstractions in C# and it take a while to "get" them if you haven't previously used a language that supported function pointers. Best avenue is through the *event* keyword. They require a callback. – Hans Passant Dec 02 '16 at 17:53
  • @HansPassant Thank you! I am trying to say that. But when somebody searches for callbacks in C#, he will see delegates. There are answers using events too ofcourse. I am looking them too but I was trying to understand why everbody uses delegates for this. – Zapdos Dec 02 '16 at 17:56

2 Answers2

0

A delegate safely encapsulates a method, a kind of a template to a function in its signature. Sometimes it is easy to think it is a pointer to a function.

In your sample, the CallbackFunction can be setted to Callback because both in its definition takes just a string argument.

You could use Action and Func instead of delegate. The difference between them is that an Action does not return something and Func does. For sample:

public void Test(Action success, Action<Exception> error)
{
    try
    {
        // perform some task
        success();
    }
    catch (Exception ex)
    {
        error(ex);
    }
}

And use it:

Test(() => { Console.WriteLine("Success"); },
     (ex) => { Console.WriteLine($"Error: {ex.Message}"); });

the generic option of an Action is the type of the arguments you can pas to this method. On the sample, Exception is a argument which is passed to error Action. The same is valid for a Func<> but the last type of a Func is the result type.

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
  • Thank you but my main problem is returning to a function in main class which a proper "callback" does after its work. I am trying to find how we can do something like this with using delegates. – Zapdos Dec 02 '16 at 17:28
0

Why do we need delegates?

Because in many programs, you need the ability to abstract the concept of a method. One reason is events, another is a set of methods like this:

public void DoWork(Action completeCallback)
{
    ... //Do Stuff
    completeCallback();
}

public void FirstMainMethod()
{
     DoWork(() => Console.WriteLine("First callback");
}

public void SecondMainMethod()
{
     DoWork(() => Console.WriteLine("Second callback");
}

In other words, different parts of my code need to have a different method run on completion, so I pass it in (I can't use a direct call). The delegate abstraction allows this. Also note that the idea of a "completion" callback in .NET is pretty silly, you almost never need it. You will use delegates for this general idea all the time though.

How can we make a callback that finally calls an OnFail() method on fail, and OnSuccess() method on success?

You can do this pretty easily. You can even make a somewhat generic one (not sure if you would ever want to mind you, but the following code works):

public void SuccessFailHelper(Func<bool> work, Action success, Action failure)
{
   if (work())
      success();
   else
      failure();
}
BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • This is the most informative reply by far. But still I did not fully understand. So we need 2 delegates for 2 results (OnFail and OnSuccess) I am going to think about this and write here again. – Zapdos Dec 02 '16 at 17:48
  • @Zapdos Yes, if you want an onFail callback and and OnSuccess callback you need two delegate "objects" if you will, you don't necessarily need two delegate *declerations* (ie, uses of the `delegate` keyword) – BradleyDotNET Dec 02 '16 at 18:14