在C#中,Select
, ToList
, 和 ToArray
都是用于集合转换的方法,它们各自有不同的用途和适用场景。
测试数据
/// <summary>
/// 设备类
/// </summary>
class Device
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 设备类型
/// </summary>
public string Type { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 测试结果
/// </summary>
public int Result { get; set; }
}
//初始化数据
List<Device> list = new List<Device>();
list.Add(new Device() { Id = 101, Name = "1号设备", Type = "生产设备", Result = 99 });
list.Add(new Device() { Id = 102, Name = "2号设备", Type = "生产设备", Result = 60 });
list.Add(new Device() { Id = 103, Name = "3号设备", Type = "测试设备", Result = 98 });
list.Add(new Device() { Id = 104, Name = "4号设备", Type = "测试设备", Result = 70 });
list.Add(new Device() { Id = 201, Name = "5号生产设备", Type = "生产设备", Result = 100 });
list.Add(new Device() { Id = 202, Name = "6号测试设备", Type = "测试设备", Result = 89 });
list.Add(new Device() { Id = 203, Name = "7号测试设备", Type = "测试设备", Result = 98 });
list.Add(new Device() { Id = 204, Name = "8号测试设备", Type = "测试设备", Result = 95 });
Select
Select
方法用于将集合中的每个元素转换成另一种形式。它接受一个 lambda 表达式,该表达式定义了如何转换每个元素。Select
返回的是一个序列,通常用于项目映射或投影。
使用场景
- 当你需要对集合中的每个元素应用一个转换,并且不需要立即执行这个转换时(即延迟执行)。
- 当你希望返回一个集合而不是具体的集合类型(如列表或数组)。
示例
在这个例子中,Select
将 devices
列表中的每个 Device
对象转换为其 Name
属性,返回一个只包含名字的序列。
// 使用 Select 映射 Devices 中的每个 Device 对象到其 Name 属性
var deviceNames = list.Select(x => x.Name);
var deviceIds = list.Select(x => x.Id);
//转换到一个新的类型
var dtos = list.Select(x => new DeviceDto { Id = x.Id, Result = x.Result });
x=> x.Name
该方法等价于一个带返回值的类型
string GetNane(Device device)
{
return device.Name;
}
Select
的结果,集合泛型的类型,决定于返回的类型。
如下示例,返回不同类型对应集合类型也随着变化,但是集合的类型都是IEnumerable
var deviceNames = list.Select(x => x.Name);
var deviceIds = list.Select(x => x.Id);
var dtos = list.Select(x => new DeviceDto { Id = x.Id, Result = x.Result });
ToList
ToList
方法将查询结果转换为 List<T>
。它会在内存中立即执行查询,并返回一个列表。
使用场景
- 当你需要一个具体类型的集合(如列表),并且希望立即执行查询时。如上所示,当我们使用
Select
或者其他方法,如Where
等集合操作时,返回类型如果是集合类型,都会返回IEnumerable
,他只提供了集合的基本操作,和相关的查询扩展方法,需要其他操作,如增加,删除, 就需要转换到List
类型
示例
using System;
using System.Collections.Generic;
using System.Linq;
public class Device
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Program
{
public static void Main()
{
List<Device> devices = new List<Device>
{
new Device { Id = 1, Name = "设备 1" },
new Device { Id = 2, Name = "设备 2" }
};
// 使用 ToList 将 Devices 转换为 List<string>
var namesList = devices.Select(device => device.Name).ToList();
// 输出每个设备的名字
foreach (var name in namesList)
{
Console.WriteLine(name);
}
}
}
在这个例子中,ToList
将 Select
的结果转换为一个列表,这意味着查询会被立即执行,并且你可以对列表进行修改。
使用场景2
foreach
循环复制副本
在使用foreach
时,我们无法对集合进行添加删除操作,如下所示,这样就会报错
此时,使用ToList()
就可以创建一个集合的副本,再对原集合进行操作,就能正常操作了。同理**ToArray
**也可以使用
foreach (var item in list.ToList())
{
list.Remove(item);
Console.WriteLine("已删除:" + item.Name);
}
ToArray
ToArray
方法将查询结果转换为 T[]
。它也会在内存中立即执行查询,并返回一个数组。
ToArray用法跟ToList基本相同,只不过返回的是一个数组,这个就看具体的使用需求了,如果对应参数需要是数组就使用这个。
使用场景
- 当你需要一个数组时,数组在大小上是不可变的,适合于固定大小的集合。
- 当你需要将结果传递给接受数组的方法时。
示例
using System;
using System.Collections.Generic;
using System.Linq;
public class Device
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Program
{
public static void Main()
{
List<Device> devices = new List<Device>
{
new Device { Id = 1, Name = "设备 1" },
new Device { Id = 2, Name = "设备 2" }
};
// 使用 ToArray 将 Devices 转换为 string[]
var namesArray = devices.Select(device => device.Name).ToArray();
// 输出每个设备的名字
foreach (var name in namesArray)
{
Console.WriteLine(name);
}
}
}
在这个例子中,ToArray
将 Select
的结果转换为一个数组,这意味着查询会被立即执行。
总结
总结来说,Select
用于转换集合里面对象的类型,从一个类型转变到另一个类型
ToList
和ToArray
主要用于集合类型转换,一般查询方法返回IEnumerable
类型,需要这两个方法转换到对应可操作的集合,这两个方法一般是配合其他方法使用,当然也可以用于List与数组互相转换。