开发者

c# "OR" event delegates returning bool

I have created a console for my game in XNA and I have a delegate for when a command has been entered. At the moment the delegate is returning a bool value. I have declared an event inside the Console class (which returns false) and then subscribed to this event from other classes. The idea is, if none of the classes that subscribe to this event return true then it is assumed that the user has entered an invalid command. However if at least one of the subscribed classes returns true then the command is assumed to be valid.

At the moment, only one class is taken into account for returning true or false, is there a way I can look at the return values of all the subscribin开发者_JAVA技巧g classes then OR their result?

Thanks,


From within the class that declares the event, you can retrieve the invocation-list of the event (assuming a field-like event). Invoking each of them individually will allow you to inspect the return value of each subscriber to the event.

For example:

public event Func<bool> MyEvent = delegate { return false; };

...     

private bool EmitMyEventAndReturnIfAnySubscriberReturnsTrue()
{
    return MyEvent.GetInvocationList()
                  .Cast<Func<bool>>()
                  .Select(method => method()) 
                  .ToList() //Warning: Has side-effects
                  .Any(ret => ret);
}

In this example, every subscriber is informed of the event - no short-circuit occurs if any of them responds affirmatively. This behaviour can be easily changed if desired by removing the call to ToList().

To be honest though, I don't really like events that return values; their semantics are not obvious to subscribers. I would change the design if at all possible.

EDIT: Corrected error in forcing full execution of the sequence based on Timwi's comment.


I figured it out just as I posed this question :P

bool handled = false;
foreach (Delegate d in CommandProcessed.GetInvocationList())
    handled |= (bool) d.DynamicInvoke (gameTime, command.ToString());

if (!handled) { } // Command Unrecognized

Where CommandProcessed is my event that classes subscribe to.
My delegate takes two arguments: gametime and command string.


I agree with the problem about events returning values as it seems off to me as well. However an alternative is you could create a new class CommandEventArgs:

class CommandEventArgs : EventArgs
{
    public DateTime GameTime {get; set; }
    public string Command {get; set;}
    public bool Valid {get; set;}
}

then use an instance of this method to invoke the event and then if the listener recognizes the command have it set Valid to true. Therefore if Valid is still false after invocation you know the command was unrecognized.

This is how .NET handles keyboard events you set KeyEventArgs.Handled to true to suppress any further action to happen with the event.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜