方法重载中的 Expression<Func<T,bool>> vs Func<T,bool>
Expression<Func<T,bool>> vs Func<T,bool> in method overloading
以下 3 种方法是我使用的库的一部分,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);
我在使用 Visual Studio 2017 时遇到以下问题。
我想提供一个谓词 Func<T,bool>
而不是 Expression<Func<T, bool>>
。
原因是我的函数比较了 class 的动态 属性,看起来像这样:
A.CallTo(() => A<Class>.That.Matches(obj => obj.DynamicProperty == "text")).MustHaveHappened();
DynamicProperty
标有 dynamic
关键字,我收到编译时错误
An expression tree may not contain dynamic operation
https://i.imgur.com/ujetxPh.png
好的我明白了。它在表达式中不受支持。
我想选择使用 Func<T, bool>
.
的重载
如果有两种方法只是谓词类型不同(表达式和函数),我该如何选择一个呢?
正如您在上面的方法定义中看到的,Func<T,bool>
重载有一个额外的 string description
参数。我希望这足以让编译器选择合适的重载。
所以我把电话改成这样:
A.CallTo(() => A<Class>.That.Matches(obj => obj.DynamicProperty == "text", "testing")).MustHaveHappened();
仍然出现相同的编译器时间错误,但是当我将鼠标悬停在 Visual Studio 中的方法上时,工具提示显示选择的方法是 Func<T,bool>
方法。
那么,为什么我仍然无法编译它并出现有关表达式树的错误信息?我不想使用任何表达式树!
所以只有当我将谓词放在一个单独的方法中时,我才设法让它编译
public bool Test(Class obj){
return obj.DynamicProperty == "text";
}
并将我的支票更改为
A.CallTo(() => A<Class>.That.Matches(Test, "testing")).MustHaveHappened();
这似乎可以解决问题。
但我仍然希望编译器将我使用 lamda 语法编写的函数视为 Func<T,bool>
而不是 Expression<Func<T,bool>>
.
这是 VS 或编译器中的错误还是我遗漏了什么?
编辑 - steps/setup 重现它
创建一个空白控制台项目替换 packages.config 和 Program.cs:
https://gist.github.com/michaelbudnik/33f3dd39df038ba1d02f01dc9659002b
编译器抱怨的表达式是 "CallTo" 方法的参数:
A.CallTo(() => mandrill.SendMessageTemplate(A<SendMessageTemplateRequest>.That.Matches(...)));
所以选择哪个 Matches 重载并不重要。
以下 3 种方法是我使用的库的一部分,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);
我在使用 Visual Studio 2017 时遇到以下问题。
我想提供一个谓词 Func<T,bool>
而不是 Expression<Func<T, bool>>
。
原因是我的函数比较了 class 的动态 属性,看起来像这样:
A.CallTo(() => A<Class>.That.Matches(obj => obj.DynamicProperty == "text")).MustHaveHappened();
DynamicProperty
标有 dynamic
关键字,我收到编译时错误
An expression tree may not contain dynamic operation
https://i.imgur.com/ujetxPh.png
好的我明白了。它在表达式中不受支持。
我想选择使用 Func<T, bool>
.
如果有两种方法只是谓词类型不同(表达式和函数),我该如何选择一个呢?
正如您在上面的方法定义中看到的,Func<T,bool>
重载有一个额外的 string description
参数。我希望这足以让编译器选择合适的重载。
所以我把电话改成这样:
A.CallTo(() => A<Class>.That.Matches(obj => obj.DynamicProperty == "text", "testing")).MustHaveHappened();
仍然出现相同的编译器时间错误,但是当我将鼠标悬停在 Visual Studio 中的方法上时,工具提示显示选择的方法是 Func<T,bool>
方法。
那么,为什么我仍然无法编译它并出现有关表达式树的错误信息?我不想使用任何表达式树!
所以只有当我将谓词放在一个单独的方法中时,我才设法让它编译
public bool Test(Class obj){
return obj.DynamicProperty == "text";
}
并将我的支票更改为
A.CallTo(() => A<Class>.That.Matches(Test, "testing")).MustHaveHappened();
这似乎可以解决问题。
但我仍然希望编译器将我使用 lamda 语法编写的函数视为 Func<T,bool>
而不是 Expression<Func<T,bool>>
.
这是 VS 或编译器中的错误还是我遗漏了什么?
编辑 - steps/setup 重现它
创建一个空白控制台项目替换 packages.config 和 Program.cs:
https://gist.github.com/michaelbudnik/33f3dd39df038ba1d02f01dc9659002b
编译器抱怨的表达式是 "CallTo" 方法的参数:
A.CallTo(() => mandrill.SendMessageTemplate(A<SendMessageTemplateRequest>.That.Matches(...)));
所以选择哪个 Matches 重载并不重要。