Hey, I wondered why is it that the return type of events such as
private void button1_Click(object sender, EventArgs e)
is always void?
An event can have a return value. But it is a BCL guideline to return void (and to have 2 parameters).
Returning a value becomes a bit confusing when you use the multicast property of events. The returned value is the value of the last handler executed. The return of all other subscribed handlers is lost, and because events are used for decoupling, you don't have much control over the order in which they are executed. This makes a return value very impractical.
It is another BCL practice to share and return information through a writable property of an EventArgs descendant, for example the Cancel
property of the Window.Closing event. All handlers can see and change this. Still a last-one-wins solution, but better.
But having said all that, you could still write:
delegate int Summer(int[] arr); // delegate
class Program
{
public event Summer OnSum; // event
void DoSum()
{
int[] data = {1, 2, 3} ;
int sum = 0;
if (OnSum != null)
sum = OnSum(data); // execute it.
}
}
In c#, Events could be of two types
1. Multicast
2. UnitCast
Multicast event are those who has more than one subscriber. when a multicast event is raised, then multiple handler would be invoked because you have subscribed more than one event handler. So, multicast event are intended to be used for calling multiple handler and multicast handler can't have return type why??
because if multicast delegate has return type, then every event handler would return some value and return value of one event handler would be replaced by the next event handler value.
suppose you have a multicast delegate as following
public delegate int buttonClick;
public event buttonClick onClick;
onClick += method1
onclick += method2
onclick += metho3
when this event would be raised then value returned by method1 will be replaced by value return by method2 and eventually value of only method3 would be received.
Therefore, in case of Multicast delegate, it is always recommend not to return any value.
but in case of unicast deleagte wherein you would have only one subscriber. So you can return value for fulfilling your purpose
So, for multicast delegate - No return type and for unicast delegate - can have return type
Multicast delegate can also return multiple values but for that event has to be raised manually.
Event in case you opt that multicast delegate should also return values, lets say I am having an event which is bind to 4 event handler and it takes two integers and one handler does add, second subtraction and third multiply and last divide. So, if you want to get the return type of all the handlers, then you have to raise the event manually in the following manner,
var handler = _eventToRaised.GetInvocationList();
foreach(var handler in handlers)
{
if(handler != null)
{
var returnValue = handler()// pass the values which delegate expects.
}
}
As a number of people have already stated this a convention not a constraint. You can have an event return things within the EventArgs itself. Microsoft uses this pattern in many places, see the FormClosing event in WinForms. So if you want to return a value do something like the following:
public class AllowCloseEventArgs : EventArgs
{
public bool AllowClose = true;
}
public void AllowClose(object sender, AllowCloseEventArgs e)
{ e.AllowClose = false; }
Knowing this now let's discuss why the designers chose the 'standard' void-return prototype of events:
Update: Ben rightfully adds: #4: what if an event needed to return more than one value?
As a college professor of mine used to say about almost every question "It depends on the implementation". In this particular case, working with event handlers, there is nothing implicit with this model that would prevent and implementation of this pattern to return something back to the calling code. However, you're passed both the sender object as well as the originating event arguments, with basically form your executing environment context, there is no need to return anything since you can work directly with those references to achieve any relevant functionality.
Other frameworks may allow for an event handler to return something.
You can't do this because the delegate that handles the event is expecting a certain signature (you'll get compile error if you try and change it). For example the delegate in this case (Button.Click) is a System.EventHandler, it has to match that signature to compile/function as a delegate at all:
public delegate void EventHandler(Object sender, EventArgs e)
This is just how delegates work, when you look at how it's usually used, it makes more sense:
MyButton.Click += button1_Click;
If you returned anything else...what would it be used for? If you intend to call something that returns a result...that's what a method is for, not an EventHandler :)