When to use callbacks instead of events in c#?
Asked Answered
C

8

50

When would you favour using a callback (i.e, passing in a Func or Action), as opposed to exposing and using an event?

UPDATE

What motivated this question was the following problem:

I have a ThingsHandler class, which can be associated with a ThingEditor. The ThingsHandler handles a list of Things, knows their order, which one is 'current', when new ones are added or deleted etc.

The ThingEditors can just modify a single thing.

The ThingsHandler needs to alert the ThingEditor when the user selects a new Thing to edit, and the ThingEditor needs to alert the ThingsHandler when the user says 'done'.

What bothers me is having these two classes holding references to each other - though I guess that's inevitable - or binding to events in both directions. I wondered if using a callback in one direction was 'cleaner'.

I suspect there is a design pattern for this.

Carlinecarling answered 7/1, 2010 at 12:57 Comment(0)
N
42

Though the other answers thus far seem reasonable, I would take a more philosophical tack.

A class is a mechanism that models a particular kind of thing in a particular domain. It is very easy when writing the internal details of a class to conflate the implementation details of the mechanism with the semantics being modeled. A brief example of what I mean:

class Giraffe : Mammal, IDisposable
{
    public override void Eat(Food f) { ... }
    public void Dispose() { ... }
}

Notice how we've conflated the real-world thing being modeled (a giraffe is a kind of mammal, a giraffe eats food) with the details of the implementation (an instance of Giraffe is an object which can be disposed of with the "using" statement). I guarantee that if you go to the zoo, you will never see a giraffe being disposed of with the using statement. We've mixed up the levels here, which is unfortunate.

I try to use events (and properties) as part of the semantic model and use callback methods (and fields) as part of the mechanism. I would make GaveBirth an event of Giraffe, since that is part of the model of real-world giraffe behaviour we're attempting to capture. If I had some mechanism, like, say I wanted to implement an inorder-walk tree traversal algorithm that walked the family tree of giraffes and called a method back on every one, then I'd say that this was clearly a mechanism and not part of the model, and make it a callback rather than try to shoehorn that into the event model.

Nonary answered 7/1, 2010 at 18:13 Comment(4)
Darn, you're making my brain hurt again :) In my current code, the classes are so far removed from anything in the real world, I'm not sure where I'd start...(see updated question)Carlinecarling
Good answer, and to summarise: events are notifications (gave birth), callbacks are requests (eat food). Relating this to the real world and you get a use-case diagram with the giraffe as the object, and the user as the animal handler (or kid with popcorn throwing it through the bars)Leathery
Not only hard to digest, but also hard to translate.. Eventually it's worth it! Thanks Eric.Mardellmarden
I think the fact that you are not allowed to assign null or method to event being outside the class that provides the event whilst you are allowed to do it internally is the significant evidence of what Eric Lippert explained. Only adding and removing methods is allowed.Pedestrianism
B
31

I use callbacks in a few cases where I know it will only ever fire once, and the callback is specific to a single method call (rather than to an object instance) - for example, as the return part of an async method.

This is particularly true of static utility methods (since you don't have an instance, and static events are deadly when used carelessly, and to be avoided), but of course the other option is to create a class instance with an event instead.

Brody answered 7/1, 2010 at 13:2 Comment(0)
L
27

Generally, I use a callback if it is required, whereas an event is used when it should be optional. Don't expose an event if you're expecting there to always be something listening.

Consider the following:

public class MyClass_Event
{
    public event EventHandler MakeMeDoWork;

    public void DoWork()
    {
        if (MakeMeDoWork == null)
            throw new Exception("Set the event MakeMeDoWork before calling this method.");
        MakeMeDoWork(this, EventArgs.Empty);
    }
}

versus:

public class MyClass_Callback
{
    public void DoWork(EventHandler callback)
    {
        if (callback == null)
            throw new ArgumentException("Set the callback.", "callback"); // better design
        callback(this, EventArgs.Empty);
    }
}

The code is almost the same as the callback can be passed as null, but at least the exception thrown can be more relevant.

Leathery answered 7/1, 2010 at 14:8 Comment(0)
O
15

Callbacks are good when one object wishes to receive a single notification (e.g. an Async data read runs and then calls you with the result).

Events are good for recurring notifications that can be received by an arbitrary number of listeners.

Oliana answered 7/1, 2010 at 13:2 Comment(0)
W
5

In terms of OO design and class coupling there isn't great deal of difference between a callback interface and an event.

However, I prefer events where they are things the class needs to "shout about" to whoever is interested in listening (usually multiple things) and callbacks where a specific class has requested an async operation.

Whatever you use, use them consistently across the codebase!

Wyon answered 7/1, 2010 at 13:3 Comment(0)
P
5

One example is when the callback should return something. E.g. (stupid example):

public int Sum(Func<int> callbackA, Func<int> callbackB) {
    return callbackA() + callbackB();
}

public void UseSum() {
    return sum(() => 10, () => 20);
}
Papyrus answered 7/1, 2010 at 14:5 Comment(0)
V
4

I would use Func or Action when I am going to call the function once or use a Lambda expression.

Events can be registered more than once which sometimes is ideal. With a callback, one has to implement a registration system for the callbacks if you want multiple.

Vareck answered 7/1, 2010 at 13:3 Comment(0)
F
-1

Well, I think they are same things. There're many different tech terms to name the same concepts or things in the different languages.

So, what do you mean "Callback" or "event handler"?

According to MSDN: Callback function is code within a managed application that helps an unmanaged DLL function complete a task.

And, MADN also gives us a introduction of the difference between them.click here

Callbacks are extensibility points that allow a framework to call back into user code through a delegate. These delegates are usually passed to the framework through a parameter of a method.

Events are a special case of callbacks that supports convenient and consistent syntax for supplying the delegate (an event handler). In addition, Visual Studio’s statement completion and designers provide help in using event-based APIs

Also, in some books, such as this book, the author seemed say the same thing with MSDN.

Therefore, in my opinion, you can't say use callbacks instead of events in the C#.

Fullbodied answered 18/10, 2015 at 21:6 Comment(1)
A callback is a language-agnostic idea of passing functionA as an argument to functionB. When certain conditions are met in functionB, functionA will be called. It's a different concept than events.Steel

© 2022 - 2024 — McMap. All rights reserved.