【发布时间】:2018-03-11 21:36:05
【问题描述】:
我很难理解为什么List<T>FindAll(...) 方法不接受Func<TSource, bool>,而是坚持接受Predicate<TSource>。
因此,当我有 List 的书籍时,我只想购买比 10 便宜的书籍。这段代码运行得很好。
Predicate<Book> CheapBooksPredicate = b => b.Price < 10;
var cheapBooksPredicate = books.FindAll(CheapBooksPredicate);
但是当我将Predicate<TSource> 更改为Func<TSource, bool>
Func<Book, bool> CheapBooksFunc = b => b.Price < 10;
var cheapBooksFunc = books.FindAll(CheapBooksFunc);
我收到错误:
参数 1:无法从 'System.Func' 转换为 'System.Predicate'
我在这里缺少什么?当Func<TSource, bool> 和Predicate<TSource> 都是predicates 时。 Predicate<TSource> 应该是 Func 的专用版本,它根据一组标准获取并评估一个值并返回一个布尔值,因此我认为它们可以在使用方面相互替换。
【问题讨论】:
-
FindAll 的定义早于
Func<>委托家族的定义,因此他们为自己的特定情况创建了自己的委托类型。委托类型与 .NET 中的所有其他类型一样,由于结构相似性,因此不兼容赋值。类型的名称很重要。 -
只需使用 LINQ:
.Where(...) -
@mikez 所以即使两者都做同样的事情,但他们有不同的名字,编译器会把它们当作两种不同的类型?
-
@Nashmár 是的。您可能会从 this question 获得更多见解,尤其是 Eric Lippert 的 cmets 和他的回答 here。简而言之,如果编译器/运行时团队不得不重新做一遍,他们可能会选择为委托实现结构类型,但到目前为止,这将是一个重大变化,这意味着它不太可能发生。
-
@mikez 我想我现在明白了。谢谢。