虽然在前面的文章里编写了一些LINQ查询,但是没有解释LINQ是如何工作的,现在,我们花点时间来正确的理解它们。
LINQ有多个组成部分,有些是必须的,而有些是可选的。
使用 Enumerable 类可以对序列(IEnumerable 接口的实现类)进行各种扩展操作,例如过滤、映射、排序等。
扩展方法 | 说明 |
---|---|
Where | 根据指定条件过滤序列中的元素。 |
Select | 对序列中的每个元素应用转换函数,返回包含结果的新序列。 |
SelectMany | 对序列中的每个元素应用转换函数,并将结果序列扁平化为单个序列。 |
Take | 从序列的开头返回指定数量的元素。 |
Skip | 跳过序列的指定数量的元素,然后返回剩余的元素。 |
OrderBy | 按升序对序列中的元素进行排序。 |
OrderByDescending | 按降序对序列中的元素进行排序。 |
Concat | 连接两个序列。 |
Distinct | 返回一个去除了重复元素的序列。 |
Union | 返回两个序列的并集(去除重复元素)。 |
Intersect | 返回两个序列的交集。 |
Except | 返回存在于第一个序列中但不存在于第二个序列中的元素。 |
Any | 确定序列是否包含任何元素或满足特定条件的元素。 |
All | 确定序列中的所有元素是否都满足指定条件。 |
Count | 返回序列中的元素数量。 |
Sum | 计算序列中数值元素的和。 |
Min | 返回序列中的最小值。 |
Max | 返回序列中的最大值。 |
Average | 计算序列中数值元素的平均值。 |
First | 返回序列中的第一个元素。 |
FirstOrDefault | 返回序列中的第一个元素,如果序列为空则返回默认值。 |
Last | 返回序列中的最后一个元素。 |
LastOrDefault | 返回序列中的最后一个元素,如果序列为空则返回默认值。 |
Single | 返回仅有一个元素的序列中的元素,如果序列为空或包含多个元素则引发异常。 |
SingleOrDefault | 返回仅有一个元素的序列中的元素,如果序列为空则返回默认值,如果包含多个元素则引发异常。 |
ElementAt | 返回序列中指定索引处的元素。 |
ElementAtOrDefault | 返回序列中指定索引处的元素,如果索引超出范围则返回默认值。 |
以上是 Enumerable 类定义的一些常用扩展方法,它们提供了对序列进行筛选、投影、排序以及聚合等多种操作。这些方法可以帮助开发人员更便捷地处理集合数据,使得对数据的操作变得更加灵活和高效。
通过使用 Where 扩展方法,我们可以便捷地对实体集合进行条件筛选,从而得到符合特定条件的子集。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<Person> people = new List<Person>
{
new Person { Name = "Alice", Age = 25 },
new Person { Name = "Bob", Age = 30 },
new Person { Name = "Charlie", Age = 22 },
new Person { Name = "David", Age = 35 }
};
// 使用 Where 方法过滤年龄大于 25 的人员
var filteredPeople = people.Where(p => p.Age > 25);
// 输出过滤后的结果
foreach (var person in filteredPeople)
{
Console.WriteLine($"{person.Name} - {person.Age}");
}
}
}
// 定义 Person 类
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
当使用 LINQ 对实体进行排序时,可以使用 OrderBy 和 OrderByDescending 方法。
使用OrderBy 和OrderByDescending 扩展方法按单个属性排序
// 按年龄升序排序
var sortedPeopleByAgeAsc = people.OrderBy(p => p.Age);
// 输出按年龄升序排序的结果
foreach (var person in sortedPeopleByAgeAsc)
{
Console.WriteLine($"{person.Name} - {person.Age}");
}
// 按姓名降序排序
var sortedPeopleByNameDesc = people.OrderByDescending(p => p.Name);
// 输出按姓名降序排序的结果
foreach (var person in sortedPeopleByNameDesc)
{
Console.WriteLine($"{person.Name} - {person.Age}");
}
使用ThenBy扩展方法按照后续属性排序
// 先按年龄升序排序,然后按身高降序排序
var sortedPeople = people.OrderBy(p => p.Age).ThenByDescending(p => p.Height);
// 输出排序后的结果
foreach (var person in sortedPeople)
{
Console.WriteLine($"{person.Name} - Age: {person.Age}, Height: {person.Height} cm");
}
根据类型进行过滤
我们使用 OfType() 方法从列表中过滤出属于 Person 类型的对象,并将结果存储在 people 中。最后,我们遍历过滤后的结果并输出每个人的姓名和年龄。
// 过滤出属于 Person 类型的对象
var people = mixedList.OfType<Person>();
// 输出过滤后的结果
foreach (var person in people)
{
Console.WriteLine($"{person.Name} - {person.Age}");
}
当使用 LINQ 处理集合时,可以通过 LINQ 提供的功能对集合进行各种操作。例如,可以使用 Where 方法来过滤集合中的元素,使用 Select 方法对元素进行投影,使用 OrderBy 和 OrderByDescending 方法对元素进行排序,使用 Sum、Average 等方法计算数值型集合元素的总和、平均值等。
以下是一个示例,展示如何使用 LINQ 处理集合:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 过滤出偶数
var evenNumbers = numbers.Where(n => n % 2 == 0);
// 输出过滤后的偶数
Console.WriteLine("偶数:");
foreach (var number in evenNumbers)
{
Console.Write(number + " ");
}
// 对奇数进行平方操作
var squaredOddNumbers = numbers.Where(n => n % 2 != 0).Select(n => n * n);
// 输出平方后的奇数
Console.WriteLine("\n奇数的平方:");
foreach (var number in squaredOddNumbers)
{
Console.Write(number + " ");
}
// 计算所有数字的和
int sum = numbers.Sum();
// 输出所有数字的和
Console.WriteLine($"\n所有数字的和为:{sum}");
}
}
希望通过本文,您对 LINQ 的组成部分以及如何使用 LINQ 处理集合数据有了更清晰的理解。LINQ 提供了强大的功能和灵活的查询方式,使得对集合数据的操作变得更加简洁、直观和高效。
如果您有任何其他关于 LINQ 或其他主题的问题,都可以随时向我提出。我将竭诚为您提供帮助。感谢您的阅读和交流!