C# LINQ 中 Select 的用法
在 C# LINQ 中,Select 是一个投影(Projection)操作符。它的核心作用是转换。
简单来说,Select 允许你遍历一个集合,并对集合中的每一个元素进行处理,然后返回一个新的集合。
1. 基本概念
- 一对一映射:输入集合有多少个元素,输出集合就有多少个元素。
- 类型转换:输入集合是
List<A>,输出集合可以是List<B>。 - SQL 类比:类似于 SQL 语句中的
SELECT column_name FROM table。
2. 常见用法详解
2.1 提取属性(最常用)
这是最常见的场景。你有一个包含复杂对象的列表,但你只需要其中的某一列数据。
class User { public string Name { get; set; } public string Email { get; set; } } List<User> users = new List<User> { new User { Name = "张三", Email = "zhang@test.com" }, new User { Name = "李四", Email = "li@test.com" } }; // 这里的 u 代表每一个 User 对象 // u.Email 表示我们只想要 Email 属性 IEnumerable<string> emails = users.Select(u => u.Email); // 结果:["zhang@test.com", "li@test.com"]
2.2 数据转换(计算或修改)
你可以在 Select 中进行运算,把数据变成另一种形式。
List<int> numbers = new List<int> { 1, 2, 3, 4 }; // 对每一个数字 n,返回 n * n var squares = numbers.Select(n => n * n); // 结果:[1, 4, 9, 16]
2.3 转换成匿名类型(DTO 转换)
当你需要从一个大对象中提取多个属性,并组合成一个新的、临时的对象时,这非常有用。
class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Description { get; set; } // 不需要这个 } List<Product> products = GetProducts(); // 创建一个新的匿名对象,只包含 Id 和 Name var simpleProducts = products.Select(p => new { p.Id, p.Name, DisplayName = p.Name + " (特价)" // 甚至可以创建新字段 }); foreach(var item in simpleProducts) { // 此时 item 是一个匿名类型 Console.WriteLine($"{item.Id}: {item.DisplayName}"); }
2.4 获取索引(Index)
Select 有一个重载版本,可以让你同时访问元素和它的索引(位置)。
语法:(element, index) ⇒ …
List<string> racers = new List<string> { "刘翔", "博尔特", "苏炳添" }; // x 是名字,i 是索引(从0开始) var results = racers.Select((x, i) => $"第 {i + 1} 名是: {x}"); // 结果: // "第 1 名是: 刘翔" // "第 2 名是: 博尔特" // "第 3 名是: 苏炳添"
3. 查询语法 vs 方法语法
虽然上面的例子都是基于方法语法 (Method Syntax),但 Select 在查询语法 (Query Syntax) 中同样重要。
| 语法类型 | 代码示例 | 说明 |
|---|---|---|
| 方法语法 | users.Select(u ⇒ u.Name) | 使用 Lambda 表达式,更简洁,支持所有操作符 |
| 查询语法 | from u in users select u.Name | 看起来更像 SQL,可读性在复杂查询时较好 |
查询语法示例:
var names = from u in users select u.Name;
4. 总结图解
假设你有一箱橙子(原始集合):
Select(橙子 ⇒ 橙子汁)- 你把每个橙子榨汁。
- 结果:一箱橙汁。(类型变了,数量不变)
Select(橙子 ⇒ 橙子.产地)- 你只看每个橙子的标签。
- 结果:一箱产地标签。(只取属性)
评论