2013-03-15 1 views
3

Je C# une méthode qui est déclarée comme suit:Comment puis-je accéder à la valeur de la cible d'un Func <Client, bool>?

public IEnumerable<ClientEntity> Search(Func<Client, bool> searchPredicate) 
{ 
    // Uses the search searchPredicate to perform a search. 
} 

Cette méthode est appelée avec quelque chose comme:

string searchCriteria = "My Search Criteria"; 
bool searchOnlyActive = false; 
myClientService.Search(c => c.Name.Contains(searchCriteria) && (c.Active || !searchOnlyActive)); 

Maintenant, si je jette un point d'arrêt au début de cette méthode et Je regarde les propriétés de searchPredicate dans la fenêtre immédiate, quand je tape searchPredicate.Target, je reçois quelque chose comme ceci:

{MyNamespace.ClientsService.} 
    searchCriteria: "My Search Criteria" 
    searchOnlyActive: false 

ce que je voudrais est d'obtenir la valeur "My Search Criteria" et la valeur false affichée ici, comme le débogueur, mais je n'ai pas réussi car le type de la propriété Target est quelque chose comme "<> c__DisplayClass2" dont je n'ai aucune idée D'où cela vient-il? Je sais que cela peut être fait parce que le débogueur le fait, je ne sais pas comment.

Des idées? Merci!

+0

Vous renvoyez correctement une classe anonium ('<> c__DisplayClass2') au lieu de vous' ClientEntity'. Essayez d'afficher le code qui préforme la recherche –

+0

"obtenir les valeurs affichées" => où? Vous les obtenez déjà dans la fenêtre immédiate. – Jon

+0

Si myClientService.Search requiert les composants internes du prédicat que vous transmettez, vous ne devez pas passer de délégué, mais une structure qui décrit ce que vous recherchez (par exemple, il peut contenir des propriétés telles que Criteria et OnlyActive). En passant un délégué, vous supprimez la logique de filtrage de cette méthode. Si vous voulez juste exécuter le prédicat sur un objet, utilisez la syntaxe 'bool isMatch = searchPredicate (someClient)'. –

Répondre

3

<>c__DisplayClass2 est la classe que le compilateur a inventée pour obtenir le contexte de capture. Vous pouvez simplement utiliser la réflexion:

object target = searchPredicate.Target; 
if(target != null) { 
    foreach(var field in target.GetType().GetFields()) { 
     Console.WriteLine("{0}={1}", field.Name, field.GetValue(target)); 
    } 
} 

qui sort:

searchCriteria=My Search Criteria 
searchOnlyActive=False 

Cependant! À moins de comprendre les méthodes anonymes et les variables capturées (et comment cela est implémenté en termes de classes de contexte générées par le compilateur), je ne pense pas que cela fera ce que vous voulez; par exemple, il pourrait y avoir aucun contexte (un Target qui est null), ou plusieurs contextes imbriqués ...

aussi: arbres d'expression via Expression<Func<Client,bool>> sont beaucoup plus inspectable, si tel est votre intention.

+0

Exactement ce dont j'avais besoin, merci! – Ceottaki

+0

Je ne m'inquiète pas trop du contexte, j'utilise seulement cette réflexion pour se moquer de quelques comportements pour les tests unitaires, donc ce sera un environnement très contrôlé. Merci encore! – Ceottaki

Questions connexes