C# Enumerable类 之 生成序列
总目录
前言
在 C# 中,System.Linq.Enumerable 类是 LINQ(Language Integrated Query)的核心组成部分,它提供了一系列静态方法,用于操作实现了 IEnumerable 接口的集合。通过这些方法,我们可以轻松地对集合进行查询、转换、排序和聚合等操作。
本文属于 C# Enumerable类 使用详解 中的一个章节,着重介绍 C# Enumerable 类中生成序列这部分的内容。
一、概览
| 方法 | 描述 | 示例 |
|---|---|---|
Repeat | 生成包含指定元素的重复序列 | Enumerable.Repeat("Hello", 5); |
Range | 生成一系列连续的整数序列 | Enumerable.Range(1, 5); |
二、Repeat :重复序列
1. 什么是 Repeat
Repeat 是 LINQ 提供的一个静态方法,用于创建一个由指定元素重复构成的序列。它适用于需要生成包含相同元素的可枚举集合的场景。
2. Repeat 方法 基本信息
1) Repeat
Enumerable.Repeat 主要用于生成一个由相同元素组成的序列。它在需要初始化一个包含相同值的集合时非常有用。
public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count);
- 参数:
element:要重复的元素。count:要生成的元素数量。
- 返回值:一个包含指定元素重复指定次数的
IEnumerable<TResult>。
2)工作原理
Repeat 方法会生成一个由指定元素重复出现的序列,重复次数由 count 参数指定。如果 count 小于等于0,则返回一个空的序列。
3)使用场景
- 初始化集合:当需要初始化一个包含相同元素的集合时,可以使用 Repeat 方法。
- 测试数据生成:在单元测试或其他测试场景中,生成包含相同元素的测试数据。
- 模拟数据:在开发过程中,模拟一些简单的数据集以验证逻辑的正确性。
3. 使用示例
示例 1:基本用法
生成重复元素的列表
static void Main(){IEnumerable<int> repeatedNumbers = Enumerable.Repeat(5, 3);foreach (var num in repeatedNumbers){Console.WriteLine(num); // 输出: 5 5 5}List<string> repeatedStrings = Enumerable.Repeat("Hello", 4).ToList();foreach (var str in repeatedStrings){Console.WriteLine(str); // 输出: Hello Hello Hello Hello}}
在这个例子中,我们使用 Enumerable.Repeat 创建了一个包含三个 5 的整数序列和一个包含四个 "Hello" 的字符串列表。
示例 2:初始化数组
static void Main(){int[] initializedArray = Enumerable.Repeat(-1, 5).ToArray();foreach (var num in initializedArray){Console.WriteLine(num); // 输出: -1 -1 -1 -1 -1}}
这里,我们使用 Enumerable.Repeat 初始化一个包含五个 -1 的数组。
示例 3:初始化集合
有时我们需要初始化一个包含相同对象的集合。例如,初始化一个包含多个相同对象的列表。
using System;
using System.Collections.Generic;
using System.Linq;class Person
{public string Name { get; set; }public int Age { get; set; }public override string ToString(){return $"{Name} ({Age})";}
}class Program
{static void Main(){var person = new Person { Name = "Alice", Age = 30 };var repeatedPersons = Enumerable.Repeat(person, 3).ToList();foreach (var p in repeatedPersons){Console.WriteLine(p); // 输出: Alice (30) Alice (30) Alice (30)}}
}
在这个例子中,我们首先使用 Where 方法筛选出了年龄大于25的人,然后使用 Select 方法只选择了这些人的名字。
示例 4:结合其他 LINQ 方法
Repeat 可以与其他 LINQ 方法结合使用,进一步增强其功能。例如,我们可以先使用 Repeat 方法生成一个序列,然后再使用 Select 方法进行转换。
using System;
using System.Collections.Generic;
using System.Linq;class Program
{static void Main(){var repeatedNumbers = Enumerable.Repeat(1, 5); // 生成5个数字1的序列var transformedNumbers = repeatedNumbers.Select(n => n * 2); // 将每个数字乘以2foreach (var num in transformedNumbers){Console.WriteLine(num); // 输出: 2 2 2 2 2}}
}
在这个例子中,我们首先使用 Repeat 方法生成了一个包含5个数字 1 的序列,然后使用 Select 方法将每个数字乘以2。
示例 5:生成复杂对象序列
我们还可以使用 Repeat 方法生成包含复杂对象的序列,并对其进行操作。例如,生成一个包含多个自定义对象的序列,并对这些对象进行修改。
using System;
using System.Collections.Generic;
using System.Linq;class Person
{public string Name { get; set; }public int Age { get; set; }public override string ToString(){return $"{Name} ({Age})";}
}class Program
{static void Main(){var initialPerson = new Person { Name = "Alice", Age = 30 };var persons = Enumerable.Repeat(initialPerson, 3).ToList();// 修改第一个对象的属性persons[0].Name = "Bob";foreach (var p in persons){Console.WriteLine(p); // 输出: Bob (30) Bob (30) Bob (30)}}
}
在这个例子中,我们生成了一个包含3个相同 Person 对象的列表,并修改了第一个对象的 Name 属性。由于所有对象实际上是指向同一个实例的引用,因此所有对象的 Name 都被修改了。
示例 6:生成不同对象的序列
为了避免上述问题(所有对象指向同一个实例),我们可以在 Repeat 方法的基础上使用 Select 方法生成不同的对象实例。
using System;
using System.Collections.Generic;
using System.Linq;class Person
{public string Name { get; set; }public int Age { get; set; }public override string ToString(){return $"{Name} ({Age})";}
}class Program
{static void Main(){var persons = Enumerable.Repeat(new { Name = "Alice", Age = 30 }, 3).Select(a => new Person { Name = a.Name, Age = a.Age }).ToList();// 修改第一个对象的属性persons[0].Name = "Bob";foreach (var p in persons){Console.WriteLine(p); // 输出: Bob (30) Alice (30) Alice (30)}}
}
在这个例子中,我们使用 Repeat 方法生成了一个匿名对象的序列,并通过 Select 方法将其转换为新的 Person 对象实例。这样,每个 Person 对象都是独立的,修改其中一个不会影响其他对象。
4. 注意事项
尽管 Where 方法非常有用,但在实际应用中也有一些需要注意的地方:
-
引用类型与值类型: 对于引用类型的对象,
Repeat方法生成的序列中的每个元素实际上是同一个对象的引用。这意味着如果修改其中一个对象,所有引用该对象的元素都会受到影响。为了避免这种情况,可以在Repeat方法的基础上使用Select方法生成新的对象实例。 -
性能考虑:
Repeat方法生成的序列是惰性执行的,只有在实际遍历时才会生成元素。这种设计可以提高性能,特别是在处理大型集合时。 -
不可变性:
Repeat方法不会修改原始元素,而是返回一个新的序列。这意味着原始元素保持不变,新的序列只包含重复的元素。 -
空集合处理: 如果 count 参数小于等于0,则
Repeat方法将返回一个空的序列。因此,在使用Repeat方法之前,通常不需要检查 count 是否大于0。
三、 Range:连续整数序列
1. 什么是 Range
Range 是 LINQ 提供的一个静态方法,用于生成一个包含从起始值开始的连续整数序列。它适用于需要生成一系列连续数字的场景,如循环控制、数组初始化等。
2. Range方法 基本信息
1)Range
Enumerable.Range 主要用于生成一系列连续的整数。它在需要生成索引、循环计数器或任何其他需要连续整数的场景中非常有用。
public static IEnumerable<int> Range(int start, int count);
- 参数:
start:序列中的第一个整数。count:要生成的连续整数的数量。
- 返回值:一个包含从
start开始的连续整数的IEnumerable<int>。
2)工作原理:
Range 方法会生成一个从 start 开始的整数序列,序列中的元素数量由 count 参数指定。如果 count 小于等于0,则返回一个空的序列。
2)使用场景
- 循环控制:当需要执行固定次数的循环时,可以使用
Range方法替代传统的 for 循环。 - 数组或列表初始化:在初始化数组或列表时,可以使用
Range方法生成初始值。 - 测试数据生成:在单元测试或其他测试场景中,生成一系列连续的整数作为测试数据。
- 模拟数据:在开发过程中,模拟一些简单的数据集以验证逻辑的正确性。
3. 使用示例
示例 1:基本用法
假设我们需要生成一个从1到5的整数序列,我们可以使用 Range 方法。
using System;
using System.Collections.Generic;
using System.Linq;class Program
{static void Main(){var numbers = Enumerable.Range(1, 5);foreach (var num in numbers){Console.WriteLine(num); // 输出: 1 2 3 4 5}}
}
在这个例子中,我们使用 Range 方法生成了一个从1开始的5个连续整数的序列,并遍历输出了这些整数。
示例 2:生成负数序列
我们也可以生成负数序列。例如,生成一个从-5到-1的整数序列。
using System;
using System.Collections.Generic;
using System.Linq;class Program
{static void Main(){var numbers = Enumerable.Range(-5, 5);foreach (var num in numbers){Console.WriteLine(num); // 输出: -5 -4 -3 -2 -1}}
}
在这个例子中,我们生成了一个从-5开始的5个连续整数的序列,并遍历输出了这些整数。
示例 3:结合其他 LINQ 方法
Range 可以与其他 LINQ 方法结合使用,进一步增强其功能。例如,我们可以先使用 Range 方法生成一个序列,然后再使用 Select 方法进行转换。
using System;
using System.Collections.Generic;
using System.Linq;class Program
{static void Main(){var numbers = Enumerable.Range(1, 5); // 生成1到5的整数序列var transformedNumbers = numbers.Select(n => n * 2); // 将每个数字乘以2foreach (var num in transformedNumbers){Console.WriteLine(num); // 输出: 2 4 6 8 10}}
}
在这个例子中,我们首先使用 Range 方法生成了一个从1到5的整数序列,然后使用 Select 方法将每个数字乘以2。
示例 4:生成多维数组的索引
有时我们需要生成多维数组的索引。例如,生成一个二维数组的所有索引对。
using System;
using System.Collections.Generic;
using System.Linq;class Program
{static void Main(){int rows = 3;int cols = 4;var indices = from row in Enumerable.Range(0, rows)from col in Enumerable.Range(0, cols)select new { Row = row, Col = col };foreach (var index in indices){Console.WriteLine($"({index.Row}, {index.Col})"); // 输出: (0, 0) (0, 1) ... (2, 3)}}
}
在这个例子中,我们使用 Range 方法生成了一个二维数组的所有索引对,并遍历输出了这些索引。
示例5:初始化集合
有时我们需要初始化一个包含连续整数的集合。例如,初始化一个包含1到10的整数的列表。
using System;
using System.Collections.Generic;
using System.Linq;class Program
{static void Main(){var numbers = Enumerable.Range(1, 10).ToList(); // 生成1到10的整数序列并转换为列表foreach (var num in numbers){Console.WriteLine(num); // 输出: 1 2 3 4 5 6 7 8 9 10}}
}
在这个例子中,我们使用 Range 方法生成了一个从1到10的整数序列,并将其转换为列表。
示例6:生成复杂的对象序列
我们还可以使用 Range 方法生成复杂的对象序列。例如,生成一组自定义对象,每个对象包含一个唯一的ID。
using System;
using System.Collections.Generic;
using System.Linq;class Person
{public int Id { get; set; }public string Name { get; set; }public override string ToString(){return $"Person {Id}: {Name}";}
}class Program
{static void Main(){var personNames = new[] { "Alice", "Bob", "Charlie", "David", "Eve" };var people = Enumerable.Range(1, personNames.Length).Select(i => new Person { Id = i, Name = personNames[i - 1] });foreach (var person in people){Console.WriteLine(person); // 输出: Person 1: Alice Person 2: Bob ...}}
}
在这个例子中,我们使用 Range 方法生成了一组自定义 Person 对象,每个对象包含一个唯一的ID和对应的名字。
4. 注意事项
- 延迟执行:
Range方法是惰性执行的,这意味着它不会立即生成整个序列,而是在实际遍历时才生成元素。这种设计可以提高性能,特别是在处理大型序列时。 - 不可变性:
Range方法不会修改原始元素,而是返回一个新的序列。这意味着原始元素保持不变,新的序列只包含生成的整数。 - 空集合处理:如果 count 参数小于等于0,则
Range方法将返回一个空的序列。因此,在使用 Range 方法之前,通常不需要检查 count 是否大于0。 - 溢出问题:如果 start + count - 1 超过了 int.MaxValue,则可能会导致溢出错误。因此,在使用 Range 方法时应确保生成的序列不会超出整数的最大范围。
四、Enumerable.Repeat vs Enumerable.Range
| 特性 | Enumerable.Repeat | Enumerable.Range |
|---|---|---|
| 目标 | 生成多个相同的元素 | 生成一系列连续的整数 |
| 参数 | element: 要重复的元素count: 元素数量 | start: 序列的第一个整数count: 整数元素数量 |
| 返回类型 | IEnumerable<TResult> | IEnumerable<int> |
| 使用场景 | 初始化包含相同值的集合 | 生成索引、循环计数器等 |
性能对比:生成百万级序列时比 for 循环慢 15%,但代码更简洁
结语
回到目录页:C#/.NET 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。
参考资料:
微软官方文档 Enumerable
相关文章:
C# Enumerable类 之 生成序列
总目录 前言 在 C# 中,System.Linq.Enumerable 类是 LINQ(Language Integrated Query)的核心组成部分,它提供了一系列静态方法,用于操作实现了 IEnumerable 接口的集合。通过这些方法,我们可以轻松地对集合…...
【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.2.2倒排索引原理与分词器(Analyzer)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 1.2.2倒排索引原理与分词器(Analyzer)1. 倒排索引:搜索引擎的基石1.1 正排索引 vs 倒排索引示例数据对比: 1.2 倒排索引核心结…...
salesforce 为什么无法关闭task,显示:insufficient access rights on object id
在 Salesforce 中,如果你在尝试关闭任务(Task)时遇到 “Insufficient access rights on object id” 错误,通常是由于以下几种可能的权限问题导致的: 1. 任务的所有权问题 Salesforce 中的任务(Task&…...
和鲸科技携手四川气象,以 AI 的力量赋能四川气象一体化平台建设
气象领域与农业、能源、交通、环境科学等国计民生关键领域紧密相连,发挥着不可替代的重要作用。人工智能技术的迅猛发展,为气象领域突破困境带来了新的契机。AI 技术能够深度挖掘气象大数据中蕴含的复杂信息,助力人类更精准地把握自然规律&am…...
linux下java Files.copy 提示文件名过长
linux下java Files.copy 提示文件名过长问题排查 系统运行时执行文件拷贝的功能的时候出现了 文件名称过长的报错提示 查询过资料后整理出了每个操作系统支持最大的文件名称长度 每个操作系统现在的文件长度不一样 Linux的 /usr/include/linux/limits.h 中做出了说明 这些限制…...
工业AR眼镜的‘芯’动力:FPC让制造更智能【新立电子】
随着增强现实(AR)技术的快速发展,工业AR智能眼镜也正逐步成为制造业领域的重要工具。它不仅为现场工作人员提供了视觉辅助,还极大地提升了远程协助的效率、优化了仓储管理。新立电子其高性能的FPC产品在AI眼镜中的应用,…...
Metal学习笔记八:纹理
到目前为止,您已经学习了如何使用片段函数和着色器为模型添加颜色和细节。另一种选择是使用图像纹理,您将在本章中学习如何作。更具体地说,您将了解: • UV 坐标:如何展开网格,以便可以对其应用纹理。 • 纹…...
一文5分钟掌握基于JWT的模拟登录爬取实战
文章目录 一、JWT简介1.1 什么是JWT?1.2 JWT的结构1.3 模拟登录流程1.4 爬取数据1.5 实战步骤 二、实战示例:基于JWT的模拟登录爬取2.1 环境准备2.2 分析登录流程2.3 编写模拟登录代码2.4 代码说明 三、处理复杂情况3.1 动态参数3.2 多因素认证3.3 刷新T…...
Idea 和 Pycharm 快捷键
一、快捷键 二、Pycharm 中怎么切换分支 参考如下 如果在界面右下角 没有看到当前所在的分支,如 “Git:master” 3. 有了 4....
fody引用c++的dll合并后提示找不到
fody引用c的dll合并后提示找不到 解决方案: 在 FodyWeavers.xml 文件中添加配置 CreateTemporaryAssemblies‘true’ 官方文档:https://github.com/Fody/Costura <Weavers xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:noN…...
HAL库 IIC写和读函数
IIC写函数:HAL_I2C_Master_Transmit (); IIC读函数:HAL_I2C_Master_Receive ();写和读函数中的从机的地址最后一位由外部硬件电路控制。 int main(void) {/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------…...
初识flutter1
为什么使用flutter, 说直白一点,就是移动UI框架, 个人认为优势是: 1.一套代码adnroid 和ios 可以使用, 代码好维护 2.原生用户界面 3.开源、免费的 开发工具: 1.下载 java 包, 根据自己的电脑配置选择 官网下载: https://www.oracle.com/java/technologies/download…...
12字符函数
一、函数strchr与strrchr 注意: 这两个函数的功能,都是在指定的字符串 s 中,试图找到字符 c。strchr() 从左往右找,strrchr() 从右往左找。字符串结束标记 ‘\0’ 被认为是字符串的一部分。 图解: 示例代码ÿ…...
QT6开发高性能企业视频会议-8 使用VSCode+Copilot AI开发
Github Copilot是Github和OpenAI推出的AI编程辅助工具,之前版本的Github Copilot只有简单的代码自动补全,根据注释生成一些代码等辅助功能。 近期Copilot有了一次大的升级,加入了Agent模式,可以实现自然语言对话讨论和最重要的&a…...
矩阵的奇异值(SVD)分解和线性变换
矩阵的奇异值(SVD)分解和线性变换 SVD定义 奇异值分解(Singular Value Decomposition,简称 SVD)是一种重要的线性代数工具,能够将任意矩阵 ( A ∈ R m n \mathbf{A} \in \mathbb{R}^{m \times n} A∈Rmn…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_rbtree_sentinel_init
ngx_rbtree_sentinel_init 定义在 src\core\ngx_rbtree.h #define ngx_rbt_black(node) ((node)->color 0) /* a sentinel must be black */#define ngx_rbtree_sentinel_init(node) ngx_rbt_black(node)初始化哨兵节点的颜色 将哨兵节点(node&a…...
数据库的sql语句
本篇文章主要用来收集项目开发中,遇到的各种sql语句的编写。 1、根据user表的role_id字段,查询role表。 sql语句:使用JOIN连接两个表 SELECT u.*,r.rolename FROM user u JOIN role r ON u.role_id r.id WHERE u.id 1; 查询结果:…...
Ubuntu2204下使用NVIDIA GeForce RTX 4090进行DeepSeek-R1-Distill-Llama-8B模型微调
Ubuntu2204下使用NVIDIA GeForce RTX 4090进行DeepSeek-R1-Distill-Llama-8B模型微调 环境准备创建Python微调环境准备数据集准备模型文件 模型微调模型预测原始模型预测微调模型预测 使用unsloth,可以方便地对大模型进行微调。以微调DeepSeek-R1-Distill-Llama-8B为…...
Bugku CTF Crypto(二)
目录 这不是md5 贝斯家族 把猪困在猪圈里 黄道十二官(宫) 抄错的字符 这不是md5 描 述: 666c61677b616537333538376261353662616566357d 分 析:题目提示这不是md5,字符中出现了d,猜测16进制 使用…...
openssl的aes128_ECB加密解密运算实例
aes128算法ECB接口 加密接口 注意事项: EVP_EncryptInit_ex初始化算法EVP_aes_128_ecb(),和密钥,key至少16BEVP_EncryptUpdate加密运算,tmplen输出已加密长度EVP_EncryptFinal_ex结束运算,如果在此仍有加密运算&…...
单片机总结【GPIO/TIM/IIC/SPI/UART】
一、GPIO 1、概念 通用输入输出口;开发者可以根据自己的需求将其配置为输入或输出模式,以实现与外部设备进行数据交互、控制外部设备等功能。简单来说,GPIO 就像是计算机或微控制器与外部世界沟通的 “桥梁”。 2、工作模式 工作模式性质特…...
动态部署Web应用程序与web.xml配置详解
文章目录 前言一、动态部署Web应用程序1.1 什么是动态部署?1.2 动态部署的步骤1.3 动态部署的优势 二、web.xml 配置文件2.1 什么是web.xml?2.2 web.xml 文件的结构2.2.1常见配置(1) 配置上下文参数(2) 配置Servlet(3)配置过滤器(…...
Rt-thread源码剖析(1)——内核对象
前言 该系列基于rtthread-nano的内核源码,来研究RTOS的底层逻辑,本文介绍RTT的内核对象,对于其他RTOS来说也可供参考,万变不离其宗,大家都是互相借鉴,实现不会差太多。 内核对象容器 首先要明确的一点是什…...
Python 的历史进程
Python:编程世界中的瑞士军刀 在当今数字化飞速发展的时代,编程语言层出不穷,而 Python 无疑是其中一颗耀眼的明珠。它以其简洁优雅的语法、强大的功能以及广泛的应用领域,成为了全球开发者炙手可热的编程语言之一。 Python 是一种…...
十一、大数据治理平台总体功能架构
大数据治理平台的功能架构图中心主题:数据治理 核心重点是建立健全大数据资产管理框架,确保数据质量、安全性、可访问性和合规性。 大数据治理平台总体功能架构图 关键功能领域 1.数据资产平台(左侧) 此部分主要关注数据资产本身…...
STM32——HAL库开发笔记23(定时器4—输入捕获)(参考来源:b站铁头山羊)
定时器有四个通道,这些通道既可以用来作为输入,又可以作为输出。做输入的时候,可以使用定时器对外部输入的信号的时间参数进行测量;做输出的时候,可以使用定时器向外输出精确定时的方波信号。 一、输入捕获 的基本原理…...
爬虫反爬:CSS位置偏移反爬案例分析与实战案例
文章目录 1. 反爬机制概述2. 反爬原理3. 案例分析4. 破解思路5. 实战样例样例1:使用Python和Selenium破解CSS位置偏移反爬样例2:电商网站商品列表CSS位置偏移反爬破解 6. 总结 1. 反爬机制概述 CSS位置偏移反爬是一种常见的反爬虫技术,通过C…...
libGL.so.1: cannot open shared object file: No such file or directory-linux022
in <module> from PyQt5.QtGui import QPixmap, QFont, QIcon ImportError: libGL.so.1: cannot open shared object file: No such file or directory 这个错误信息表示XXXX 在启动时遇到问题,缺少 libGL.so.1 文件。libGL.so.1 是与 OpenGL 图形库相关的共…...
向量数据库milvus部署
官方文档 Milvus vector database documentationRun Milvus in Docker (Linux) | Milvus DocumentationMilvus vector database documentation 按部署比较简单,这里说一下遇到的问题 一:Docker Compose 方式部署 1、镜像无法拉取,(docker.io被禁) …...
修改`FSL Yocto Project Community BSP`用到的u-boot源码,使其能适配百问网(100ask)的开发板
前言 在博文 https://blog.csdn.net/wenhao_ir/article/details/145547974 中,我们利用官方提供的BSP(FSL Yocto Project Community BSP)构建了写到SD卡中的完整镜像,然后启动后发现存在不少问题,首要的问题就是u-boot不能识别网卡,在这篇博文中,我们就找到FSL Yocto Pro…...
