Following 3 methods are part of a library I use, FakeItEasy:
public static T Matches<T>(this IArgumentConstraintManager<T> scope, Func<T, bool> predicate, string description);
public static T Matches<T>(this IArgumentConstraintManager<T> manager, Func<T, bool> predicate, string descriptionFormat, params object[] args);
public static T Matches<T>(this IArgumentConstraintManager<T> scope, Expression<Func<T, bool>> predicate);
I have following problem when using Visual Studio 2017.
I want to provide a predicate as a Func<T,bool>
not Expression<Func<T, bool>>
.
The reason for that is my function compares a dynamic property of a class and looks like this:
A.CallTo(() => A<Class>.That.Matches(obj => obj.DynamicProperty == "text")).MustHaveHappened();
DynamicProperty
is marked with a dynamic
keyword and I'm getting compile time error saying
An expression tree may not contain dynamic operation
https://i.stack.imgur.com/FoQdO.png
Ok, I get it. It's not supported in expressions.
I would like to choose an overload that uses Func<T, bool>
.
If there were two methods that would just differ in the type of predicate (expression and func) how do I choose one over another?
As you can see in above methods definitions the Func<T,bool>
overload has an additional string description
parameter. I would expect that this would be enough for compiler to choose a proper overload.
So I've changed my call to be like this:
A.CallTo(() => A<Class>.That.Matches(obj => obj.DynamicProperty == "text", "testing")).MustHaveHappened();
Still getting the same compiler time error but when I hover over the method in Visual Studio now the tooltip says the method chosen is the Func<T,bool>
one.
So why I still cannot compile it with an error saying something about expression trees? I don't want to use any expression trees!
So I've managed to get it to compile only if I put the predicate in a separate method
public bool Test(Class obj){
return obj.DynamicProperty == "text";
}
And change the my check to be
A.CallTo(() => A<Class>.That.Matches(Test, "testing")).MustHaveHappened();
This seems to do the trick.
But I would still expect the compiler to treat the function I wrote using lamda syntax to be treated as a Func<T,bool>
not Expression<Func<T,bool>>
.
Is this a bug in VS or the compiler or am I missing something?
EDIT - steps/setup to reproduce it
Create a blank console project replace packages.config and Program.cs:
https://gist.github.com/michaelbudnik/33f3dd39df038ba1d02f01dc9659002b