tags:

views:

142

answers:

4

This is the call:

 bool isValid = true;
 if (this.ExternalConstraint != null)
 {
   isValid &= this.ExternalConstraint(this, EventArgs.Empty);
 }
 if (isValid)
 {
  //...
 }

The event look like:

public delegate bool externalConstraint(object sender, EventArgs args);
event externalConstraint ExternalConstraint;

When debugging I notice that all method attached to the event is called but only the last return seem to return to this line : isValid &= this.ExternalConstraint(this, EventArgs.Empty);. How can I get the event to return every method or to handle the all return value to take a decision?

+5  A: 

You can use Delegate.GetInvocationList on the delegate and process the return values individually.

Jason
+1  A: 

You would iterate on the result from ExternalConstraint.GetInvocationList instead of just calling the Constraint delegate.

ctacke
+3  A: 

Create a custom EventArgs class with a method for add return code. Each listener can then call the method, and after the event completes, you can iterate through the return codes. This also allows you to add data about which listener returned what, or why.

private class MyEventArgs : EventArgs {
   public void addReturnCode(bool retCode){
       //...
   }

   public IList<bool> getReturnCodes(){
       //...
   }

}
C. Ross
Good suggestion, I guess it's the simplest solution. I'll take a look at .GetInvocationList too. Thank for the answer.
Daok
+3  A: 

It's considered bad practice to depend on return values when using events. Rather, you should use a user-defined EventArgs to get back results.

public class ConstraintEventArgs : EventArgs
{
    public bool IsValid { get; set; }
}

It's also important to implement some mechanism in which multiple event listeners won't override each other's values. Most of the time (with a boolean flag), we will allow (or encourage) users to only explicitly turn it on (never off).

For example, with CancelEventArgs it's never a good idea to set it to false explicitly; Users should always set it to true or do nothing. The same idea should apply here with IsValid.

Bryan Menard