您的位置:首页 > 娱乐 > 明星 > C#开发-集合使用和技巧(四)集合中常用的查询方法

C#开发-集合使用和技巧(四)集合中常用的查询方法

2024/10/6 20:39:26 来源:https://blog.csdn.net/qq_39427511/article/details/139710836  浏览:    关键词:C#开发-集合使用和技巧(四)集合中常用的查询方法

集合中常用的查询方法

  • 测试数据准备:
  • 查询方法详解
    • **Where**条件查询
      • 定义和注释:
      • 功能
      • 详细说明:
      • 应用实例
        • 查找所有设备类型为“生产设备”的对象
      • 结果测试:
        • 查询所有测试结果大于90的设备
        • 多条件查询:类型为生产设备同时测试结果大于90的设备
    • **First/FirstOrDefault**
      • 功能:
      • 示例:
        • 查找id为xxx的设备
        • 查询id大于200的设备
      • 方法区别:
        • 示例:查找一个不存在的设备
      • 定义和注释:
    • **All**
      • 功能:
      • 示例:
        • 查询是否所有设备都达标(测试结果大于90)
    • **Any**
      • 功能:
      • 示例:
    • **Count**
      • 功能:
      • 示例:
      • 获集合数量
        • 获取生产设备的数量
  • 总结
  • 完整示例

本篇介绍集合的各种查询方法和使用

主要介绍条件查询Where,单个对象查询First/FirstOrDefault、功能查询All、Any、Count等

测试数据准备:

定义 一个Device 类,包括设备ID,名称,类型和测试结果,然后初始化添加4条数据

     /// <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 });

当然,让我详细介绍一下这些常用的 LINQ 查询方法:

查询方法详解

Where条件查询

定义和注释:

// 摘要:
//     根据条件过滤序列中的值。
//
// 参数:
//   source:
//     要过滤的 IEnumerable`1 类型的序列。
//
//   predicate:
//     测试每个元素是否满足条件的函数。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     包含输入序列中满足条件的元素的 IEnumerable`1。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 或 predicate 为 null。
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);// 摘要:
//     基于条件过滤序列中的值。每个元素的索引在谓词函数的逻辑中被使用。
//
// 参数:
//   source:
//     要过滤的 IEnumerable`1 类型的序列。
//
//   predicate:
//     测试源元素是否满足条件的函数;函数的第二个参数代表源元素的索引。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     包含来自输入序列中满足条件的元素的 IEnumerable`1。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 或 predicate 为 null。
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);

功能

用于过滤集合中的元素,返回一个新的集合,其中包含满足指定条件的所有元素。

详细说明:

该方法适用于所有继承于IEnumerable<TSource>的集合,传入参数为一个Func<TSource, bool> predicate委托,可以是一个参数为TSource类型,返回值为bool的方法或者Lambda表达式;方法返回一个新的IEnumerable<TSource>的集合。

应用实例

查找所有设备类型为“生产设备”的对象
  //Lambdavar productionDevices = list.Where(device => device.Type == "生产设备");//方法var productionDevices2 = list.Where(ProductDevice);bool ProductDevice(Device device)
{return device.Type == "生产设备";
}

结果测试:

将结果打印出来,可以看到上面两种方法效果一致,后续不一一演示两种方法,以Lambda的形式为主。
在这里插入图片描述

运行结果:
在这里插入图片描述

查询所有测试结果大于90的设备
  var device90s = list.Where(device => device.Result >= 90);

在这里插入图片描述

多条件查询:类型为生产设备同时测试结果大于90的设备
var pro90Devices = list.Where(x => x.Type == "生产设备" && x.Result >= 90);

First/FirstOrDefault

功能:

返回集合中的第一个元素,如果集合为空,First 方法会抛出异常,而 FirstOrDefault 会返回该类型的默认值。

示例:

查找id为xxx的设备
  var dev1 = list.First(x => x.Id == 101);var dev2 = list.FirstOrDefault(x => x.Id == 101);Console.WriteLine("\n单设备查找:");Console.WriteLine($"ID: {dev1.Id}, 名称: {dev1.Name}, 结果: {dev1.Result}");Console.WriteLine($"ID: {dev2.Id}, 名称: {dev2.Name}, 结果: {dev2.Result}");
查询id大于200的设备
  var dev1 = list.First(x => x.Id > 200);

此时有多个满足的设备,但是他只会返回第一个

在这里插入图片描述

方法区别:

First 方法会抛出异常,而 FirstOrDefault 会返回该类型的默认值。

示例:查找一个不存在的设备
var dev2 = list.FirstOrDefault(x => x.Id == 0);
var dev1 = list.First(x => x.Id == 0);

可以看到使用FirstOrDefault 返回了一个null,也就是这个类型的默认值,而使用First 直接报错了,这个就根据自己需要去使用不同方法

在这里插入图片描述

定义和注释:

// 摘要:
//     返回序列中的第一个元素。
//
// 参数:
//   source:
//     要从中返回第一个元素的 IEnumerable`1 序列。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     序列中的第一个元素。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 为 null。
//
//   T:System.InvalidOperationException:
//     序列为空。
public static TSource First<TSource>(this IEnumerable<TSource> source);// 摘要:
//     返回序列中满足指定条件的第一个元素。
//
// 参数:
//   source:
//     要从中返回元素的 IEnumerable`1 序列。
//
//   predicate:
//     测试每个元素是否满足条件的函数。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     序列中通过指定谓词函数测试的第一个元素。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 或 predicate 为 null。
//
//   T:System.InvalidOperationException:
//     没有元素满足谓词条件。 - 或 - 序列为空。
public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);// 摘要:
//     返回序列中的第一个元素,如果序列不包含元素,则返回默认值。
//
// 参数:
//   source:
//     要从中返回第一个元素的 IEnumerable`1 序列。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     如果序列为空,则返回 default(TSource);否则,返回序列中的第一个元素。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 为 null。
public static TSource? FirstOrDefault<TSource>(this IEnumerable<TSource> source);// 摘要:
//     返回序列中的第一个元素,如果序列不包含元素,则返回默认值。
//
// 参数:
//   source:
//     要从中返回第一个元素的 IEnumerable`1 序列。
//
//   defaultValue:
//     序列为空时返回的默认值。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     如果序列为空,则返回 defaultValue;否则,返回序列中的第一个元素。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 为 null。
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue);// 摘要:
//     返回序列中满足条件的第一个元素或默认值,如果没有这样的元素则返回默认值。
//
// 参数:
//   source:
//     要从中返回元素的 IEnumerable`1 序列。
//
//   predicate:
//     测验每个元素是否满足条件的函数。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     如果序列为空或没有任何元素通过谓词测试,则返回 default(TSource);否则,返回序列中通过谓词测试的第一个元素。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 或 predicate 为 null。
public static TSource? FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);// 摘要:
//     返回序列中满足条件的第一个元素或默认值,如果没有这样的元素则返回默认值。
//
// 参数:
//   source:
//     要从中返回元素的 IEnumerable`1 序列。
//
//   predicate:
//     测验每个元素是否满足条件的函数。
//
//   defaultValue:
//     如果序列为空时返回的默认值。
//
// 类型参数:
//   TSource:
//     序列中元素的类型。
//
// 返回结果:
//     如果序列为空或没有任何元素通过谓词测试,则返回 defaultValue;否则,返回序列中通过谓词测试的第一个元素。
//
// 异常:
//   T:System.ArgumentNullException:
//     source 或 predicate 为 null。
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, TSource defaultValue);

All

功能:

检查集合中的所有元素是否都满足指定条件。

示例:

查询是否所有设备都达标(测试结果大于90)
 var result = list.All(x => x.Result > 90);

在这里插入图片描述

Any

功能:

检查集合中是否至少有一个元素满足指定条件。

示例:

查询是否有大于等于一个设备都达标(测试结果大于90)

var result2 = list.Any(x => x.Result > 90);

在这里插入图片描述

Count

功能:

返回满足指定条件的元素数量。

示例:

获集合数量

不加任何参数就是返回集合中对象的数量

 var count = list.Count();
获取生产设备的数量
var count2 = list.Count(device => device.Type == "生产设备");

在这里插入图片描述

总结

看了上面这些示例,可以发现,有些查询条件都是类似的,不同方法,用法都是一样的,属于一个类似if中的判断表达式,作为Lambda表达式主体,就可以达到效果,不同的方法就是查询的结果和功能不同。

完整示例

这些方法在处理集合时非常有用,特别是当你需要对集合进行条件筛选、查找单个元素或者统计信息时。

下面是使用这些方法的完整示例:

 internal class Program{static void Main(string[] args){Console.WriteLine("Hello, World!");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});// 使用LINQ查询方法// 1. 选择所有设备名称var deviceNames = list.Select(device => device.Name);// 输出结果Console.WriteLine("\n所有设备名称:");foreach (var name in deviceNames){Console.WriteLine(name);}// 过滤生产设备var productionDevices = list.Where(device => device.Type == "生产设备");var productionDevices2 = list.Where(ProductDevice);Console.WriteLine("\n生产设备:");foreach (var device in productionDevices){Console.WriteLine($"ID: {device.Id}, 名称: {device.Name}, 结果: {device.Result}");}Console.WriteLine("\n生产设备:");foreach (var device in productionDevices2){Console.WriteLine($"ID: {device.Id}, 名称: {device.Name}, 结果: {device.Result}");}//Wherevar device90s = list.Where(device => device.Result >= 90);Console.WriteLine("\n生产合格设备:");foreach (var device in device90s){Console.WriteLine($"ID: {device.Id}, 名称: {device.Name}, 结果: {device.Result}");}var pro90Devices = list.Where(x => x.Type == "生产设备" && x.Result >= 90);//First/FirstOrDefaultvar dev1 = list.First(x => x.Id == 101);var dev2 = list.FirstOrDefault(x => x.Id == 101);//var dev1 = list.First(x => x.Id == 0);  //报错//var dev2 = list.FirstOrDefault(x => x.Id == 0);//var dev1 = list.First(x => x.Id > 200);//var dev2 = list.FirstOrDefault(x => x.Id > 200);Console.WriteLine("\n单设备查找:");Console.WriteLine($"ID: {dev1.Id}, 名称: {dev1.Name}, 结果: {dev1.Result}");Console.WriteLine($"ID: {dev2.Id}, 名称: {dev2.Name}, 结果: {dev2.Result}");Console.WriteLine("\n All方法测试");var result = list.All(x => x.Result > 90);Console.WriteLine($"result: {result}");Console.WriteLine("\n Any方法测试");var result2 = list.Any(x => x.Result > 90);Console.WriteLine($"result: {result2}");Console.WriteLine("\nCount方法示例");var count = list.Count();var count2 = list.Count(device => device.Type == "生产设备");Console.WriteLine($"count: {count}");Console.WriteLine($"count2: {count2}");}static bool ProductDevice(Device device){return device.Type == "生产设备";}}/// <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; }}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com