Removing multicast delegate based on return value
I have a class that has a multicast delegate:
class Signaler
{
public delegate bool SomeAction(string s);
public SomeAction Actors {get; set;}
void SignalActors()
{
Actors("blah blah");
}
}
What I would like to do is to have an actor removed from Actors when that actor returns false as part of handling its action. What would be a good way to do this in the SignalActors() function?
Update: Possible solution based on John Skeet's solution:
class Signaler
{
public delegate bool SomeAction(string s);
public SomeAction Actors {get; set;}
void SignalActors()
{
SomeAction canceledSubscri开发者_JAVA百科ptions=null;
if (Actors!=null)
foreach (SomeAction actor in Actors.GetInvocationList())
if (!actor("Blah blah blah"))
canceledSubscriptions+=actor;
if (canceledSubscriptions!=null)
foreach (SomeAction actor in canceledSubscriptions.GetInvocationList())
Actors-=actor;
}
}
The simplest way is probably to actually build up a new delegate of all the ones that return true:
void SignalActors()
{
SomeAction newActors = null;
foreach (SomeAction actor in Actors.GetInvocationList())
{
if (actor("Blah blah blah"))
{
newActors += actor;
}
}
Actors = newActors;
}
EDIT: The reason this is simpler than using -= is that it's obviously correct in terms of ordering. Whereas += always adds to the end of the invocation list, -= also takes away from the end of invocation list... so if you remove actors in the forward order, you can have a problem. Suppose we have the following actors:
A - returns false
B - returns true
C - returns true
A - (duplicate of the first) returns true this time
You should end up with {B, C, A} but if you subtract A from {A, B, C, A} you'll end up with {A, B, C}. My approach avoids this problem.
加载中,请稍侯......
精彩评论