Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a standard way to implement "Vetoable" events?

Tags:

c#

events

I'm using events as part of a game model, and for extensibility and code "locality's" sake I need to be able to veto most actions.

More clearly, nearly every method that has a side effect takes this form:

public event TryingToDoSomethingHandler TryingToDoSomething;
public event SomethingHappenedHandler   SomethingHappened;

/*
 * Returning true indicates Something happened successfully.
 */
public bool DoSomething(...)
{
  //Need a way to indicate "veto" here
  TryingToDoSomething(...);

  //Actual do it

  SomethingHappened(...);

  return true;
}

What I'd like is for TryingToDoSomething(...) to be able to indicate that a registered event handler objects (via returning false, modifying an out parameter, or something). So that the code is morally equivalent to:

/*
 * Returning true indicates Something happened successfully.
 */
public bool DoSomethingImproved(...)
{
  //Pretty sure multicast delegates don't work this way, but you get the idea
  if(!TryingToDoSomething(...)) return false;

  //Actual do it

  SomethingHappened(...);

  return true;
}

Is there an accepted or standard way to do this in C#/.NET?

like image 519
Kevin Montrose Avatar asked Jun 23 '09 23:06

Kevin Montrose


2 Answers

Are you thinking about Cancelable events? The framework uses that extensively.

Create a EventArgs class that has a Cancel property that implements get/set. The event handler can then set the Cancel property to true, which you can check when the call returns.

public bool TrySomething()
{
    CancelEventArgs e = new CancelEventArgs(); 
    if (Event1 != null) Event1.Invoke(e);
    if (e.Cancel == false)
    {
        if (Event2 != null) Event2.Invoke(e);
    }
}
like image 189
Chris Thompson Avatar answered Oct 23 '22 23:10

Chris Thompson


Take a look at the CancelEventHandler and CancelEventArgs classes. They follow a pattern where each event handler can cancel the event.

like image 40
adrianbanks Avatar answered Oct 23 '22 22:10

adrianbanks