我有以下代码片段。我对后面提到的代码片段几乎没有疑问。
var salaries = customerList
.Where(c => c.Age > 30)
.Select(c => c.Salary) // salary is of type long
.ToList();
- 在上面的代码片段中,“Where”如何访问 customerList 以及它如何定义“c”的类型?
- 在应用 Select 作用的过滤器后,“Where”是否返回一个临时的客户列表?
- “Select”究竟如何知道它必须只返回“Salary”?
- 变量“salaries”的类型如何设置为List
?
最佳答案
Where
可能是这样实现的(请注意,这是一个非常粗略的实现,只是让您了解它是什么样的):
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
foreach (T t in source) {
if (predicate(t)) {
yield return t;
}
}
}
请注意 Where
是一种扩展方法。您实际上是在调用 Where(customerList, c => c.Age > 30)
.现在你应该看到它从哪里获得了 customerList
的访问权限。 .它还推断出什么 T
应该看什么样的IEnumerable
customerList
是。因为它是 IEnumerable<Customer>
, T
是Customer
, 所以它期望一个 Func<Customer, bool>
对于第二个参数。这就是它知道 c
的方式是Customer
.
Where
不返回临时列表。许多 LINQ 方法都使用延迟求值。 Where
返回 IEnumerable<Customer>
即被过滤。请记住 IEnumerable
只是一系列事情。此序列由 Where
返回但是,除非您提出要求,否则不会进行评估。 Select
也一样。因此,在您调用 ToList
之前不会创建列表.
您的第三个问题有点像问“Where
如何知道如何过滤”或“Console.WriteLine
如何知道如何写入屏幕”。这就是Select
做。如果需要,您可以查看它的实现。这是一个粗略的草图:
public static IEnumerable<U> Select<T, U>(this IEnumerable<T> source, Func<T, U> mapping) {
foreach (T t in source) {
yield mapping(t);
}
}
变量类型salaries
通过查看您调用的每个方法的方法签名来确定。你的Select
调用返回 IEnumerable<long>
, 和 ToList
的签名告诉编译器,给定一个 IEnumerable<T>
它会返回 List<T>
,所以在这种情况下,它返回一个 List<long>
.
关于c# - "Where"和 "Select"在 LINQ 中如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59208192/