我有以下代码段。我对它后面提到的代码段有很少的疑问。
var salaries = customerList
.Where(c => c.Age > 30)
.Select(c => c.Salary) // salary is of type long
.ToList();
答案 0 :(得分:5)
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>
。
答案 1 :(得分:1)
Enumerable类中存在where子句,用于在.net框架中进行查询。它提供布尔条件和返回源。最终它将转换为相应的sql查询。
所以你的linq
var salaries = customerList
.Where(c => c.Age > 30)
.Select(c => c.Salary) // salary is of type long
.ToList();
旧式sql命令
SELECT [c].[Salary] FROM [CustomerList] WHERE [c].[Age] > '30'
答案 2 :(得分:1)
答案 3 :(得分:1)
“哪里”如何获得对customerList的访问以及如何定义 “ c”的类型?
Where()
是List类型的扩展方法。因此Where()
方法可用于customerList。 c => c.Age > 30
是Where()
子句中的谓词定义。该谓词帮助列表可根据条件筛选出数据。这里的c
表示列表中存在的单个元素。“选择”如何确切地知道它仅返回 “薪水”?
customer
中的每个customerList
。由于Customer类包含名为long类型的Salary的属性,因此Select谓词将创建对象的新形式,该对象将仅包含Salary
类的Customer
属性的值。变量“ salaries”的类型如何设置为List
?
Select()
将仅使用Salary属性创建新表单,例如new {
public long Salary{get; set;}
}
.ToList()会将Select返回的IEnumerable
转换为List
。最终,您会得到List<long>
“哪里”在应用了“ 筛选器对Select起作用?
IEnumerable
方法的过滤列表(精确度Select()
)我建议您阅读Linq in C#,Where clause,Select method,List。
答案 4 :(得分:1)
link from @Amit可以提供一个好主意。
最简单的答案是LINQ是基于称为Expressions的编译器功能构建的。当您编写类似Where(c => c.Age > 18)
的内容时,编译器实际上并不会像常规方法一样完全编译c=> c.Age > 18
。
它建立一个语法树,描述该代码的作用。
Where
函数使用它来构建一个SQL查询,该查询被发送到执行该SQL查询以获取结果的SQL服务器。
建议您查看IQueryable
和Expression<TDelegate>
的工作原理以获取更多信息。
还有助于理解difference between IEnumerable and IQueryable。
在C#其他部分(如Razor页面)中使用的表达式的另一个示例,其使用的函数类似LabelFor(...),该函数使用您 express 的属性来构建HTML标签,而不是执行代码。 / p>
HTH