当前位置:首页 > 技术 > 正文内容

C# Array类型深度剖析

访客 技术 2026年6月10日 1

Array是所有一维和多维数组的基类,提供统一的集合操作接口。无论数组声明方式如何,所有数组实例都共享相同的核心方法集。

当声明数组时,CLR会生成继承自Array的派生类型,该类型自动实现泛型集合接口如IList。数组元素在内存中连续存储,确保高效索引访问,但创建后长度不可变。

数组支持值类型和引用类型元素存储。值类型直接内联存储,而引用类型仅存储对象指针。以下示例展示内存布局差异:

var textBuilders = new StringBuilder[4];
textBuilders[0] = new StringBuilder("text1");
textBuilders[1] = new StringBuilder("text2");

var values = new double[3];
values[0] = 12.34;
values[1] = 56.78;
内存布局对比图

数组本身是引用类型,赋值操作仅复制引用。深度比较需使用结构化比较器:

object[] set1 = { "text", 100, false };
object[] set2 = { "text", 100, false };

Console.WriteLine(set1 == set2);  // 输出False

var comparer = StructuralComparisons.StructuralEqualityComparer;
Console.WriteLine(comparer.Equals(set1, set2));  // 输出True

Clone方法创建浅拷贝副本:

var cloned = (StringBuilder[])textBuilders.Clone();
浅拷贝示意图

动态创建与访问

除字面量声明外,可通过反射动态创建数组:

Array dynArray = Array.CreateInstance(typeof(string), 2);
dynArray.SetValue("Hello", 0);
string val = (string)dynArray.GetValue(0);

多维数组访问示例:

void PrintFirstElement(Array arr)
{
    int[] indices = new int[arr.Rank];
    Console.WriteLine(arr.GetValue(indices));
}

var matrix = new int[,] { { 10, 20 }, { 30, 40 } };
PrintFirstElement(matrix);  // 输出10

遍历与维度

数组遍历方式:

int[] data = { 10, 20, 30 };
Array.ForEach(data, Console.WriteLine);  // 输出10\n20\n30

维度操作方法:

int[,,] cube = new int[2,3,4];
Console.WriteLine(cube.GetLength(1));  // 输出3
Console.WriteLine(cube.Rank);          // 输出3

搜索与排序

二分查找要求数组有序:

int[] sorted = { 5, 10, 15 };
int pos = Array.BinarySearch(sorted, 10);  // 返回1

条件查找示例:

string[] items = { "apple", "banana", "cherry" };
string result = Array.Find(items, s => s.StartsWith("b"));  // 返回banana

双数组协同排序:

int[] ids = { 3, 1, 2 };
string[] names = { "C", "A", "B" };
Array.Sort(ids, names);  // names变为["A","B","C"]

复制与转换

数组复制方法对比:

int[] source = { 1, 2, 3 };
int[] target = new int[3];

// 浅拷贝
Array.Copy(source, target, source.Length);

类型转换示例:

float[] floats = { 1.2f, 3.4f };
int[] integers = Array.ConvertAll(floats, f => (int)f);  // 得到[1,3]

调整数组大小会创建新数组:

Array.Resize(ref source, 5);  // 新数组长度为5
标签: C#

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。