tags:

views:

937

answers:

6

Events also 'does' something like methods, but they don't have return types and just voids?

I am curious to know, Why is it so? and Why don't they return types?

+15  A: 

Because events can be handled by multiple listeners. There is not guaranteed order to the event handlers (though I think they're called in the order they are subscribed in reality.)

Instead, for events that want to "return" some data, the convention is to have a mutable EventArgs object such as CancelEventArgs which can have its Cancel property set to true. The advantage of this over a return value is that event handlers in the chain can look at the property to see if another handler already set it. But you still wind up with a situation where the last one to set the property wins.

If it were a return value, the whole concept would be a lot more complicated.

Josh Einstein
Yes multiple event handlers would certainly prove troublesome with determining where all those asynchronous returns came from.
ChrisBD
+1; good answer.
Fredrik Mörk
@ChrisBD - the process for getting feedback from individual handlers is well-defined; it isn't really any different to when you use a mutable "args" type.
Marc Gravell
@Marc - Yes I forgot about the mutable args type for .NET but then I've never seen a use for it as I have always understood that events are really a means of decoupling processing between the sender and the receiver. With the sender not knowing or caring about who handles the event that it raises and that any necessary synchronisation was to be handled by the delegate "bridge" between them.Handling a return type on an event just seems to be a fudge to me and makes me wonder whether you should really be using events if you need to process it.
ChrisBD
+3  A: 

They don't need to. Think about it. What would they return?

musicfreak
+1 Exactly what I was going to write. What would they return, what would they return it too and what could it do with it?
Robin Day
...and not least; who will return it?
Fredrik Mörk
It's actually pretty useful for an event to "return" data. For example, the AssemblyResolve event of the AppDomain class allows you to dynamically load an assembly and return it to the AppDomain. The issue is why .NET chose to use mutable EventArgs parameters instead of return values.
Josh Einstein
@Josh - I agree; most commonly, though, the reason for mutable EventArgs is (I suspect) so that different handlers can inspect the current value - for example with CancelEventArgs different handlers might set/reset the flag. With a return value, different handlers have no visibility of the value that other handlers returned. This can be a good thing or a bad thing, of course.
Marc Gravell
Of course, but there are also those classes of events that only usually expect a single handler (such as the aforementioned AssemblyResolve event) in which case a return value could be used, but by convention the EventArgs works just as well.
Josh Einstein
A: 

This is because an Event is an asynchronous call. You can have multiple copies of the same event being processed at the same time.

Hence they only pass information as in order to process a return type the event raiser would have to synchronise and wait for the event handler to complete. This would make it just like any other procedure call.

ChrisBD
Event handlers are called sequentially, synchronously though their order is undefined. All hell would break loose if they weren't.
Josh Einstein
I don't think that is true; I think event handlers execute on the thread on which the event was raised in a synchronous manner.
Fredrik Mörk
Perhaps I didn't explain myself as clearly as I should have.What I meant was that the occurance of an event cannot be predetermined by the code that handles it. The handling code does not need to be on the same thread as the event raiser and you certainly don't want the code that raises the event to wait for the handler to complete which is what it would have to do if it were to return a variuable type.
ChrisBD
A: 

Firing an event is a one-way signal. They are mostly used to achieve loose coupling, because the raiser of the event have no dependency on the consumer. A return value would create a dependency on the consumer.

Vizu
While I agree it isn't a good idea - I don't agree that it is one-way isn't; Invoke (the most commonly used approach) is synchronous, and it is quite common to accept feedback (on the "args", for example CancelEventArgs). Publishing a return type is not very different to a mutable args, and creates no additional dependency.
Marc Gravell
I see your point that C# evenst (ie. the tooling) enables feedback from the event consumer, but I think that the concept of an event is still a one-way notification, and mechanisms like CancelEventArgs is a hack of the concept.
Vizu
+4  A: 

Actually, events can have return values; simply, it isn't a good idea as it requires more complex processing when there may be multiple listeners... more commonly, there might be a settable property an an EventArgs subclass.

But here's an example of using return values with events; this is not usually a good idea; for information only:

using System;
delegate int SomeBizarreEvent(object sender); // non-standard signature
class Foo {
    public event SomeBizarreEvent Bizarro;    
    public void TestOverall() {
        SomeBizarreEvent handler = Bizarro;
        if (handler != null) {
            Console.WriteLine(handler(this));
        }
    }
    public void TestIndividual() {
        SomeBizarreEvent handler = Bizarro;
        if (handler != null) {
            foreach (SomeBizarreEvent child in handler.GetInvocationList()) {
                Console.WriteLine(child(this));
            }
        }
    }
}
class Program {
    static void Main() {
        Foo foo = new Foo();
        foo.Bizarro += delegate { return 1; };
        foo.Bizarro += delegate { return 5; };
        // writes 5 (the last result wins)
        foo.TestOverall();
        // writes 1, 5
        foo.TestIndividual();
    }
}
Marc Gravell
Great point. I actually forgot about it (though I did say in my answer) that it's only by convention that return values aren't used.
Josh Einstein
A: 

It's in the design of event system... The primary purpose of event system is notification not acknowledgment.

Event is a way to notify to it's listeners (observers) that a significant action have occurred. It's not designed in such a way to not only notify the listeners that a significant action have occurred and also acknowledge to event source that it is what???? being handled??? or else... How you decide what to do???

If an event needs to return a value where would it returned it if no handler is associated with it. What if an event have multiple handlers... Then how to decide which handlers value should be returned.

Above all this events can return values. Though it's not a best practice.

S M Kamran
Many events provide a feedback loop; the most common example being CancelEventArgs. Regardless of a return-value vs mutable-args, the mechanism for inspecting the result from individual handlers is well-defined.
Marc Gravell
I said "The primary purpose of event system is notification not acknowledgment."... I didn't said that it can't..However as you mentioned for some cases yes event should acknowledge the source with some user feedback... Like CancelEventArgs.... But making this shouldn't be a necessary case. We know that the Event Raising thread then needs to save its states or freeze (in case of blocking call) till the feedback arrive from its consumer. This adds complexities..
S M Kamran
Like the old tested observer pattern... You register observers on Observable then when observable needs to notify or signal its observer about a certain trigger he calls invoke the registered method of the observer...Again the primary target of the observer pattern is to notify it's consumer about certain triggers.. and not necessary to take the feed back of observers.If that is the case then either you do a blocking call to notify observer, or create a new thread to handle notify.
S M Kamran
Further to make thing worst...Adding n observers means this notification system will take n * k time to complete a cycle whether it be Sync or Sync.
S M Kamran