Lunivore Lunivore - 5 months ago 20
C# Question

How can I convert a Predicate<T> to an Expression<Predicate<T>> to use with Moq?

Please help this Linq newbie!

I'm creating a list inside my class under test, and I would like to use Moq to check the results.

I can easily put together a Predicate which checks the results of the list. How do I then make that Predicate into an Expression?

var myList = new List<int> {1, 2, 3};

Predicate<List<int>> myPredicate = (list) =>
return list.Count == 3; // amongst other stuff

// ... do my stuff

myMock.Verify(m => m.DidStuffWith(It.Is<List<int>>( ??? )));

??? needs to be an
if you can get your head round that many generics. I've found answers which do this the other way round and compile an Expression into a Predicate. They're not helping me understand Linq any better, though.

EDIT: I've got it working with methods; with expressions; I would just like to know if there's any way to do it with a lambda with a body - and if not, why not?



Predicate<List<int>> myPredicate = (list) => list.Count == 3;


Expression<Predicate<List<int>>> myPredicate = (list) => list.Count == 3;

The compiler does the magic for you. With some caveats1, any lambda dealing only with expressions (no blocks) can be converted into an expression tree by wrapping the delegate type (in this case Predicate<List<int>>) with Expression<>. As you noted, you could then invert it yet again by calling myPredicate.Compile().

1 For example, async lambdas (i.e. async () => await Task.Delay(1);) cannot be converted to an expression tree.

Update: You simply cannot use the compiler to arrive at the expression tree you want if it includes statements. You'll have to build up the expression tree yourself (a lot more work) using the static methods in Expression. (Expression.Block, Expression.IfThen, etc.)