C# 数组与字符串:全面解析与应用实践
在C#编程语言中,数组和字符串是两种最基础也是最重要的数据类型。无论是简单的控制台应用程序,还是复杂的企业级系统,数组和字符串都扮演着不可或缺的角色。本文将全面深入地探讨C#中数组和字符串的特性、使用方法、性能考量以及实际应用场景,帮助开发者掌握这些核心概念,并能在实际项目中灵活运用。
第一部分:C#数组详解
1.1 数组的基本概念
数组是C#中用于存储相同类型元素的固定大小的集合。它是一种引用类型,存储在堆内存中。数组的主要特点包括:
-
类型统一:数组中的所有元素必须是同一数据类型
-
固定大小:数组在创建时就确定了长度,无法动态改变
-
索引访问:通过从0开始的整数索引访问元素
-
连续内存:元素在内存中是连续存储的
1.2 一维数组的使用
一维数组是最简单的数组形式,也是最常用的。以下是创建和使用一维数组的完整示例:
// 声明数组的多种方式
int[] numbers1 = new int[5]; // 声明长度为5的整型数组
int[] numbers2 = new int[] {1, 2, 3, 4, 5}; // 声明并初始化
int[] numbers3 = {6, 7, 8, 9, 10}; // 简化的初始化语法// 访问和修改数组元素
numbers1[0] = 100; // 设置第一个元素
int firstElement = numbers2[0]; // 获取第一个元素// 遍历数组的几种方法
// 1. 使用for循环
for (int i = 0; i < numbers1.Length; i++)
{Console.WriteLine($"Index {i}: {numbers1[i]}");
}// 2. 使用foreach循环
foreach (int num in numbers2)
{Console.WriteLine(num);
}// 3. 使用Array.ForEach方法
Array.ForEach(numbers3, Console.WriteLine);
1.3 多维数组与锯齿数组
1.3.1 多维数组
多维数组适用于表示表格、矩阵等数据结构。C#支持二维、三维甚至更高维度的数组。
// 二维数组示例
int[,] matrix = new int[3, 4]; // 3行4列的矩阵
matrix[0, 0] = 1; // 第一行第一列
matrix[2, 3] = 12; // 最后一行最后一列// 初始化二维数组
int[,] predefinedMatrix = {{1, 2, 3},{4, 5, 6},{7, 8, 9}
};// 遍历二维数组
for (int row = 0; row < predefinedMatrix.GetLength(0); row++)
{for (int col = 0; col < predefinedMatrix.GetLength(1); col++){Console.Write($"{predefinedMatrix[row, col]} ");}Console.WriteLine();
}
1.3.2 锯齿数组(Jagged Array)
锯齿数组是数组的数组,每个子数组可以有不同的长度。
// 创建锯齿数组
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[] {1, 2, 3};
jaggedArray[1] = new int[] {4, 5};
jaggedArray[2] = new int[] {6, 7, 8, 9};// 访问元素
int value = jaggedArray[1][0]; // 4// 遍历锯齿数组
for (int i = 0; i < jaggedArray.Length; i++)
{for (int j = 0; j < jaggedArray[i].Length; j++){Console.Write($"{jaggedArray[i][j]} ");}Console.WriteLine();
}
1.4 数组的常用方法和属性
C#数组提供了许多有用的方法和属性:
int[] numbers = {5, 3, 8, 1, 9};// 长度属性
int length = numbers.Length; // 5// 排序
Array.Sort(numbers); // 1, 3, 5, 8, 9// 反转
Array.Reverse(numbers); // 9, 8, 5, 3, 1// 查找元素索引
int index = Array.IndexOf(numbers, 5); // 2// 复制数组
int[] copy = new int[numbers.Length];
Array.Copy(numbers, copy, numbers.Length);// 清空数组
Array.Clear(numbers, 0, numbers.Length);
1.5 数组的性能考量
-
内存效率:数组在内存中是连续存储的,访问速度快
-
固定大小:创建后无法改变大小,可能导致内存浪费或空间不足
-
插入/删除成本:在数组中间插入或删除元素需要移动后续元素
-
适合场景:元素数量已知且不常变化的场景
第二部分:C#字符串深入解析
2.1 字符串的基本特性
C#中的字符串是System.String类的实例,具有以下重要特性:
-
不可变性(Immutability):字符串一旦创建就不能修改,任何"修改"操作都会创建新字符串
-
Unicode编码:支持国际化字符集
-
引用类型:虽然表现类似值类型,但实际上是引用类型
-
字符串池(String Interning):编译时会优化相同字符串的内存使用
2.2 字符串的创建与初始化
// 创建字符串的多种方式
string str1 = "Hello World"; // 直接赋值
string str2 = new string('*', 10); // **********
char[] letters = {'A', 'B', 'C'};
string str3 = new string(letters); // "ABC"// 逐字字符串(@)与转义字符
string path1 = "C:\\Windows\\System32"; // 需要转义
string path2 = @"C:\Windows\System32"; // 不需要转义// 多行字符串
string multiLine = @"第一行
第二行
第三行";
2.3 字符串的常用操作
2.3.1 基本操作
string text = "C# Programming Language";// 长度
int len = text.Length; // 22// 访问字符
char firstChar = text[0]; // 'C'// 连接字符串
string combined = text + " by Microsoft"; // 使用+运算符
string concat = string.Concat(text, " ", "is powerful"); // 使用Concat方法
2.3.2 字符串比较
string a = "hello";
string b = "HELLO";// 区分大小写比较
bool equal1 = a.Equals(b); // false
bool equal2 = a.Equals(b, StringComparison.OrdinalIgnoreCase); // true// == 运算符
bool equal3 = (a == b); // false// Compare方法
int result = string.Compare(a, b, StringComparison.OrdinalIgnoreCase); // 0表示相等
2.3.3 字符串查找与截取
string sentence = "The quick brown fox jumps over the lazy dog";// 查找子字符串
int index1 = sentence.IndexOf("fox"); // 16
int index2 = sentence.LastIndexOf("the"); // 31// 检查开头和结尾
bool starts = sentence.StartsWith("The"); // true
bool ends = sentence.EndsWith("dog"); // true// 子字符串
string sub1 = sentence.Substring(4, 5); // "quick"
string sub2 = sentence[16..19]; // C# 8.0的切片语法 "fox"
2.3.4 字符串修改
string original = " Hello World ";// 修剪空白
string trimmed = original.Trim(); // "Hello World"// 替换
string replaced = original.Replace("World", "C#"); // " Hello C# "// 大小写转换
string upper = original.ToUpper(); // " HELLO WORLD "
string lower = original.ToLower(); // " hello world "// 插入和删除
string inserted = original.Insert(5, ","); // " He,llo World "
string removed = original.Remove(5, 3); // " He World "
2.3.5 字符串分割与连接
// 分割字符串
string csv = "apple,orange,banana,grape";
string[] fruits = csv.Split(','); // ["apple", "orange", "banana", "grape"]// 连接字符串数组
string[] words = {"The", "quick", "brown", "fox"};
string joined1 = string.Join(" ", words); // "The quick brown fox"
string joined2 = string.Join("-", words); // "The-quick-brown-fox"
2.4 字符串格式化
// 复合格式化
string formatted1 = string.Format("Today is {0:yyyy-MM-dd}", DateTime.Now);// 字符串插值(C# 6.0+)
string name = "Alice";
int age = 25;
string formatted2 = $"My name is {name} and I'm {age} years old";// 数字格式化
double price = 19.99;
string priceStr = price.ToString("C"); // "$19.99"
string percent = 0.25.ToString("P"); // "25.00%"
2.5 StringBuilder类
由于字符串的不可变性,频繁修改字符串会导致性能问题。StringBuilder类提供了高效的字符串构建方式:
using System.Text;StringBuilder sb = new StringBuilder();// 追加内容
sb.Append("Hello");
sb.AppendLine(" World!"); // 自动添加换行
sb.AppendFormat("Today is {0:dddd}", DateTime.Now);// 插入和删除
sb.Insert(5, ",");
sb.Remove(5, 1);// 容量管理
sb.EnsureCapacity(100); // 确保最小容量// 获取最终字符串
string result = sb.ToString();
StringBuilder特别适用于:
-
需要大量字符串连接的循环中
-
构建大型或复杂的字符串
-
需要频繁修改字符串内容的场景
第三部分:数组与字符串的交互
3.1 字符串与字符数组的转换
// 字符串转字符数组
string str = "Hello";
char[] chars = str.ToCharArray();// 字符数组转字符串
char[] letters = {'A', 'B', 'C'};
string newStr = new string(letters); // "ABC"// 修改字符串中的字符(通过字符数组)
char[] temp = str.ToCharArray();
temp[0] = 'J'; // 修改第一个字符
string modified = new string(temp); // "Jello"
3.2 字符串与字节数组的转换
// 字符串转字节数组
string text = "Hello";
byte[] bytes = Encoding.UTF8.GetBytes(text);// 字节数组转字符串
string decoded = Encoding.UTF8.GetString(bytes);// 不同编码的转换
byte[] unicodeBytes = Encoding.Unicode.GetBytes(text);
string fromUnicode = Encoding.Unicode.GetString(unicodeBytes);
3.3 字符串分割为数组与数组合并为字符串
// 复杂字符串分割
string data = "Name:John;Age:30;City:New York";
string[] pairs = data.Split(';'); // ["Name:John", "Age:30", "City:New York"]// 进一步分割
foreach (string pair in pairs)
{string[] keyValue = pair.Split(':');Console.WriteLine($"Key: {keyValue[0]}, Value: {keyValue[1]}");
}// 多维数组转换为字符串
int[,] matrix = { {1, 2}, {3, 4} };
StringBuilder sb = new StringBuilder();
for (int i = 0; i < matrix.GetLength(0); i++)
{for (int j = 0; j < matrix.GetLength(1); j++){sb.Append(matrix[i, j] + " ");}sb.AppendLine();
}
string matrixString = sb.ToString();
第四部分:实际应用场景
4.1 数组的应用场景
-
数据处理:存储和处理大量同类型数据
-
算法实现:排序、搜索等算法的基础数据结构
-
游戏开发:存储游戏对象、地图数据等
-
图像处理:像素数据的存储和处理
-
数学计算:矩阵运算、向量计算等
4.2 字符串的应用场景
-
文本处理:日志分析、文档处理
-
数据序列化:JSON、XML等格式的字符串处理
-
用户输入验证:表单验证、数据清洗
-
报告生成:动态构建报告内容
-
网络通信:HTTP请求和响应的处理
4.3 性能优化建议
-
数组优化:
-
预分配足够大的数组以避免频繁扩容
-
考虑使用Buffer.BlockCopy进行字节数组的高效复制
-
对于数值计算,考虑使用Span<T>或Memory<T>减少内存分配
-
-
字符串优化:
-
避免在循环中使用字符串连接,改用StringBuilder
-
使用StringComparison.Ordinal进行不需要文化敏感性的比较
-
考虑使用string.Create方法减少内存分配
-
对于只读场景,考虑使用ReadOnlySpan<char>处理字符串
-
结语
数组和字符串作为C#中最基础的数据类型,它们的理解和掌握程度直接影响着编程效率和应用性能。通过本文的系统讲解,我们不仅了解了它们的基本用法,还深入探讨了高级特性和性能考量。在实际开发中,应根据具体场景选择最合适的数据结构和操作方法,平衡代码的可读性、可维护性和性能需求。
随着C#语言的不断发展,数组和字符串的处理方式也在不断优化(如Span<T>、Memory<T>等新特性的引入)。作为开发者,我们应该持续学习这些新特性,将它们应用到实际项目中,以编写出更高效、更健壮的代码。
相关文章:

C# 数组与字符串:全面解析与应用实践
在C#编程语言中,数组和字符串是两种最基础也是最重要的数据类型。无论是简单的控制台应用程序,还是复杂的企业级系统,数组和字符串都扮演着不可或缺的角色。本文将全面深入地探讨C#中数组和字符串的特性、使用方法、性能考量以及实际应用场景…...
前端vue中使用signalr
一、引入SignalR库 使用NPM引入SignalR库 npm install @microsoft/signalrJs文件中引入 import * as signalR from @microsoft/signalr;二、初始化连接 这一步需要指定SignalR Hub的URL。 const connection = new signalR.HubConnectionBuilder().withUrl("https://y…...
Stable Diffusion底模对应的VAE推荐
以下是主流Stable Diffusion底模对应的VAE推荐表格: 底模版本推荐VAE类型说明SD1.5SD1.5专用VAE通常使用vae-ft-mse-840000-ema-pruned.safetensorsSD2.0SD1.5兼容VAE或SD2专用VAE部分SD2模型需配套512-ema-only.vae.ptSD3内置VAESD3系列模型通常自带集成VAE无需额…...
centos7.5安装kubernetes1.25.0
centos7.5安装kubernetes centos7.5kubernetes1)准备阶段准备2台虚拟机配置静态IP修改主机名桥接设置配置阿里云的repo源配置k8s切国际源配置时间同步安装基础软件包 2)安装containerd服务安装配置开启启动 3)安装k8s4)安装kubersphere下载helm安装包解压将helm配置…...

AT2659S射频前端芯片技术解析:L1频段低噪声高增益GNSS信号放大
以下是关于AT2659S L1频段卫星导航射频前端芯片的客观描述,严格基于用户提供的原始信息,采用分享式表述,保持参数和核心内容不变: AT2659S芯片概述 AT2659S是一款基于SiGe工艺的射频前端芯片,专为L1频段&#…...

ROS2学习(15)------ROS2 TF2 机器人坐标系管理器
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 ROS版本:2 在 ROS 2 中,TF2(Transform Library, v2) 是一个非常核心的工具库,用于管理多个坐标系之间的 变换关系(tran…...
每日c/c++题 备战蓝桥杯(洛谷P3382 三分法求极值详解)
洛谷P3382 三分法求极值详解 题目描述 P3382 三分法 要求在给定区间内寻找一个多项式函数的最大值点。题目保证函数在区间内先严格递增后严格递减(单峰函数),适合使用三分法求解。 算法原理 三分法核心思想 对于单峰函数,在区…...

Vue+css实现扫描动画效果(使用@keyframes scan)
实现效果 扫描效果 参考链接 MDN Web Docs: CSS Animations 关键代码 示例代码 <div class"scanner-container"><div class"scanner-line"></div><div class"scanner-icon">📷</div><p>Scan m…...
Windows 配置 ssh 秘钥登录 Ubuntu
在 Windows 上推送 SSH 公钥到远程服务器(类似于 Linux 上的 ssh-copy-id)可以通过以下几种方法实现: ** 手动复制公钥内容** 查看本地公钥内容:type $env:USERPROFILE\.ssh\id_rsa.pub登录远程服务器,将公钥内容粘贴…...
Conda:环境移植及更新1--使用conda-pack
更多内容:XiaoJ的知识星球 目录 一、使用conda-pack1.安装 conda-pack2.移植整个 Anaconda 环境3.移植单个虚拟环境4.验证是否生效 在相同Linux设备上移植Miniconda3(Anaconda3同理)常用方法有。 使用conda-pack:使用conda-pack工…...
github好玩的工具
以下是 GitHub 上一些有趣且实用的开源工具推荐,涵盖 AI 应用、效率提升、趣味开发等方向,结合最新趋势和项目热度整理: 一、AI 与深度伪造工具 Deep-Live-Cam 仅需一张图片即可在视频直播中实时替换人脸,适用于内容创作和虚拟角色开发,支持多平台硬件运行(如 NVIDIA CUD…...

PHP学习笔记(九)
箭头函数 箭头函数是 PHP 7.4的新语法。是一种更简洁的匿名函数的写法,它们都是closure类的实现。 箭头函数的基本语法为fn(argument_list) > expr 箭头函数支持与匿名函数相同的功能,只是其父作用域的变量总是自动的。 当表…...
共现矩阵的SVD降维与低维词向量计算详解
共现矩阵的SVD降维与低维词向量计算详解 1. 原始共现矩阵构建 根据用户提供的共现对: 句子1: (I, like), (like, apples)句子2: (I, like), (like, bananas) 词汇表:[I, like, apples, bananas] 窗口大小2(假设共现对直接作为矩阵的非零元…...

信创 CDC 实战 | OGG、Attunity……之后,信创数据库实时同步链路如何构建?(以 GaussDB 数据入仓为例)
国产数据库加速进入核心系统,传统同步工具却频频“掉链子”。本系列文章聚焦 OceanBase、GaussDB、TDSQL、达梦等主流信创数据库,逐一拆解其日志机制与同步难点,结合 TapData 的实践经验,系统讲解从 CDC 捕获到实时入仓࿰…...
PyQt学习系列08-插件系统与模块化开发
PyQt学习系列笔记(Python Qt框架) 第八课:插件系统与模块化开发 (原课程规划中的第12课,按用户要求调整为第9课) 课程目标 掌握Qt插件系统的原理与开发方法实现可扩展的模块化应用程序理解QPluginLoader动…...
Redis核心数据结构操作指南:字符串、哈希、列表详解
注:此为苍穹外卖学习笔记 Redis作为高性能的键值数据库,其核心价值来自于丰富的数据结构支持。本文将深入解析字符串(String)、哈希(Hash)、**列表(List)**三大基础结构的操作命令&…...

微服务(SpringCloud)的简单介绍
一.什么是微服务? 微服务是一种软件架构风格,核心思想是用职责单一的小型项目,组合出复杂的大型项目。 二.举例 1.单体架构(SpringBoot) 无论项目中有多少功能,都是放在一个项目中。 如下图所示࿱…...

Python 爬虫开发
文章目录 1. 常用库安装2. 基础爬虫开发2.1. 使用 requests 获取网页内容2.2. 使用 BeautifulSoup 解析 HTML2.3. 处理登录与会话 3. 进阶爬虫开发3.1. 处理动态加载内容(Selenium)3.2. 使用Scrapy框架3.3. 分布式爬虫(Scrapy-Redisÿ…...

第十一周作业
一、实现bluecms旁注,并解释为什么旁站攻击可以拿下主站?跨库的意思是什么? 1、为什么旁站攻击可以拿下主站 因为主站业务和旁站业务共处于同一个服务器上面,当我们无法攻破主站业务时,可以通过攻破旁站业务…...

猿大师办公助手网页编辑Office/wps支持服务器文件多线程下载吗?
浏览器兼容性割裂、信创替代迫切的2025年,传统WebOffice控件因依赖NPAPI/PPAPI插件已无法适配Chrome 107等高版本浏览器。猿大师办公助手通过系统级窗口嵌入技术,直接调用本地Office/WPS内核,实现: 真内嵌非弹窗:将Of…...

英码科技携带 “无感知AI数字课堂”解决方案,亮相第22届广东教育装备展
5月23日至25日,第22届广东教育装备展览会在广州国际采购中心盛大举行。作为华为生态重要合作伙伴,英码科技携“无感知AI数字课堂解决方案”重磅登场,聚焦教学提质增效,为教育数字化转型注入新动能。 聚焦课堂真实场景,…...
各个链接集合
golang学习~~_从数组中取一个相同大小的slice有成本吗?-CSDN博客 框架 golang学习~~_从数组中取一个相同大小的slice有成本吗?-CSDN博客 golang k8s学习_容器化部署和传统部署区别-CSDN博客 K8S rabbitmq_rabbitmq 广播-CSD…...

【R语言科研绘图】
R语言在绘制SCI期刊图像时具有显著优势,以下从功能、灵活性和学术适配性三个方面分析其适用性: 数据可视化库丰富 R语言拥有ggplot2、lattice、ggpubr等专业绘图包,支持生成符合SCI期刊要求的高分辨率图像(如TIFF/PDF格式&#…...
Linux Shell 切换
在 Linux 系统中,切换至 Bash Shell 在 Linux 系统中,切换至 Bash Shell 的方法如下: 临时切换到 Bash 直接在终端输入以下命令,启动一个新的 Bash 会话: bash 退出时输入 exit 或按 CtrlD 返回原 Shell。 永久切换…...

ProfiNet转Ethernet/IP网关选型策略适配西门子S7-1500与罗克韦尔ControlLogix5580的关键指标对比
一、行业背景 新能源汽车电池制造是当前工业自动化领域增长最快的细分市场之一。随着动力电池产能扩张与技术迭代,产线对高精度装配、实时数据交互和系统兼容性提出了更高要求。在某头部电池企业的模组装配线中,面临着不同品牌设备通信协议不兼容的问题&…...
AWS WebRTC:获取信令服务节点和ICE服务节点
建立WebRTC的第一步是获取信令服务节点和ICE服务节点。 前提条件是有访问AWS的密钥,主要是ak,sk,token,我这边是业务云有接口可以返回这些信息,所以我直接从业务云获取。 先介绍一下什么是ak,skÿ…...

[图文]图6.3会计事项-Fowler分析模式的剖析和实现
1 00:00:02,090 --> 00:00:05,160 Fowler在书里面也说了,6.4 2 00:00:05,290 --> 00:00:07,540 这里也说了 3 00:00:08,030 --> 00:00:11,340 不是常用的 4 00:00:12,520 --> 00:00:15,060 更倾向用6.2,实际上就是6.3了 5 00:00:15,760 …...
[Linux] 利用systemd实现周期性执行任务(DDNS设置案例)
利用systemd实现周期性执行任务 文章目录 利用systemd实现周期性执行任务一、引言二、systemd定时任务基础1. systemd.timer单元的基本概念和工作原理2. systemd.timer与cron的异同对比3. systemd.timer支持的时间规范格式 三、创建systemd定时任务四、管理与监控定时任务1. 定…...
maven 3.0多线程编译提高编译速度
mvn package 默认只使用 单线程 来执行构建生命周期(即顺序地构建每一个模块)。 如果你使用的是多模块项目,Maven 从 3.0 开始提供了**并行构建(parallel build)**的能力,但它不是默认开启的。 如何启用多…...
Dalvik虚拟机、ART虚拟机与JVM的核心区别
一、架构设计差异 指令集架构 JVM:基于栈结构,所有操作(如算术运算、方法调用)均依赖操作数栈完成,指令集紧凑但执行效率较低(需频繁内存交互)。Dalvik&#x…...