Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I access the value of the target of a Func<Client, bool>?

Tags:

c#

linq

I have C# a method that is declared as the following:

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

This method gets called with something like:

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

Now, if I throw a breakpoint at the beginning of that method and I look at the searchPredicate properties in the Immediate Window, when I type searchPredicate.Target, I get something like this:

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

What I would like is to actually get the "My Search Criteria" value and the false value displayed there, like the debugger does, but I didn't manage to as the type of the Target property is something like "<>c__DisplayClass2" which I have no idea where that came from. I know it can be done because the debugger does it, I just don't know how.

Any ideas? Thanks!

like image 480
Ceottaki Avatar asked Oct 21 '25 06:10

Ceottaki


1 Answers

<>c__DisplayClass2 is the class that the compiler invented to get the capture context. You can just use reflection:

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

which outputs:

searchCriteria=My Search Criteria
searchOnlyActive=False

However! Unless you understand anonymous methods and captured variables (and how that is implemented in terms of compiler-generated context classes), I don't think this will do what you want it to; for example, there could be no context (a Target that is null), or multiple nested contexts...

Also: expression trees via Expression<Func<Client,bool>> are far more inspectable, if that is your intent.

like image 106
Marc Gravell Avatar answered Oct 22 '25 22:10

Marc Gravell