7
votes

c # "ou" des délégués d'événements renvoyant bool

J'ai créé une console pour mon jeu à XNA et j'ai un délégué pour quand une commande a été entrée. Pour le moment, le délégué retourne une valeur BOOL. J'ai déclaré un événement à l'intérieur de la classe Console (qui retourne faux), puis souscrit à cet événement d'autres classes. L'idée est que, si aucune des classes qui souscrivant à cet événement ne renvoie true, il est supposé que l'utilisateur a entré une commande non valide. Toutefois, si au moins une des classes souscrites renvoie true, la commande est supposée être valide.

Pour le moment, une seule classe est prise en compte pour le retour du vrai ou de la fausse, existe-t-il un moyen de regarder les valeurs de retour de toutes les classes abonnées alors ou de leur résultat?

merci,


1 commentaires

Nice Q - Afaik Une simple affectation renvoie toujours le résultat du dernier abonné seulement.


3 Réponses :


6
votes

de l'intérieur de la classe qui déclare l'événement, vous pouvez récupérer la liste d'invocation de l'événement (en supposant un événement comme un champ). Invoquant chacun d'eux individuellement vous permettra d'inspecter la valeur de retour de chaque abonné à l'événement.

Par exemple: P>

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);
}


6 commentaires

N'aurait pas eu lieu à moi d'utiliser Linq pour cela. Bonne réponse.


J'ai regardé deux designs différents et c'était le nettoyeur de ces deux. Et c'est assez facile à comprendre et à mettre en œuvre. Je ne connais pas Linq mais j'ai trouvé une solution alternative comme je l'ai décrit ci-dessous.


@Dave: la solution alternative que vous avez postée a la même idée que ma réponse - l'astuce consiste à accéder à la liste d'invocation. Super.


@Kirk Woll: Merci. Je me demandais si je ne devais pas utiliser Linq pour cela en raison de la nature essentielle de la requête, mais je pensais que ce n'était pas un aspect important de cette question, alors allait de l'avant avec elle.


Pourquoi ne pas supprimer la sélection et la toliste et juste faire . Nany (méthode => méthode ()); ?


@Chuck: Il s'agit de forcer toutes les méthodes d'abonné à exécuter et non à court-circuit une fois qu'un abonné spécifique retourne true (regardez la solution de la OP). Bien sûr, si cela n'est pas souhaité, ce que vous suggérez serait mieux.



3
votes

Je l'ai compris comme je posais cette question: P

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

if (!handled) { } // Command Unrecognized


1 commentaires

Oui, je devais résoudre ce même problème récemment pour la validation en chaîne. Le boeuf ou l'opérateur n'est pas court-circuit comme le booléen ou l'opérateur.



0
votes

Je suis d'accord avec le problème des événements qui renvoient des valeurs telle qu'elle me semble aussi bien. Cependant, une alternative est que vous pouvez créer une nouvelle classe CommandEventargs : xxx

puis utilisez une instance de cette méthode pour appeler l'événement, puis si l'auditeur reconnaît la commande a Il définit valide sur true. Par conséquent, si valide est toujours faux après l'invocation que vous connaissez la commande n'était pas reconnue.

Voici comment .NET gère les événements de clavier que vous définissez keeventtargs.Hangled sur true pour supprimer toute action supplémentaire pour se produire avec l'événement.


0 commentaires