c# - "Where"和 "Select"在 LINQ 中如何工作?

标签 c# linq

我有以下代码片段。我对后面提到的代码片段几乎没有疑问。

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> , TCustomer , 所以它期望一个 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/

相关文章:

c# - 操纵 XElement 对象而不是 XML 文本的编辑器控件

C# 类数组

c# - WebRequest - 防止重定向

c# - 根据项目中的属性替换数组项目

c# - GroupBy 和 Sum

c# - LINQ问题我想获取每个寄存器的表的最后记录

c# - AsQueryable() 的目的是什么?

c# - 无法从另一个类访问 List<string>

c# - 通用扩展方法中的嵌套 Func<T, object>

c# - 将 EWS 代码转换为冷融合