C# 自定义类型的数组与 Array 类
### C# 自定义类型的数组与 Array 类:深入解析与应用实践
在C#(.NET)编程中,数组是存储同类型元素的集合,而自定义类型数组与系统提供的`Array`类结合使用,能高效处理复杂数据结构。本文将系统阐述自定义类型数组的声明、初始化、操作方法,以及`Array`类的核心功能(如排序、搜索、扩容等),并通过代码示例展示实际应用场景。
一、自定义类型数组的基础操作
#### 1.1 自定义类型的定义
自定义类型(如类、结构体)是数组元素的基础。例如,定义一个`Person`类:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
public override string ToString()
{
return $"{Name}, {Age}岁";
}
}
该类包含`Name`和`Age`属性,并重写了`ToString()`方法以便输出。
#### 1.2 自定义类型数组的声明与初始化
声明自定义类型数组需指定元素类型(如`Person[]`),初始化可通过以下方式:
**方式1:静态初始化(指定元素)**
Person[] people1 = new Person[]
{
new Person("张三", 25),
new Person("李四", 30)
};
**方式2:动态初始化(指定长度)**
Person[] people2 = new Person[3];
people2[0] = new Person("王五", 28);
people2[1] = new Person("赵六", 35);
**方式3:简化语法(C# 3.0+)**
var people3 = new[]
{
new Person("孙七", 22),
new Person("周八", 40)
};
#### 1.3 数组的基本操作
**访问元素**:通过索引(从0开始)获取或修改元素。
Console.WriteLine(people1[0]); // 输出:张三, 25岁
people1[1].Age = 31; // 修改李四的年龄
**遍历数组**:使用`foreach`或`for`循环。
foreach (var person in people1)
{
Console.WriteLine(person);
}
for (int i = 0; i
二、Array 类的核心功能
`Array`类是所有数组的基类,提供静态方法操作数组(如排序、搜索、复制等)。
#### 2.1 排序:`Array.Sort()`
**对自定义类型数组排序**需实现`IComparable`接口或传入比较器。
**方式1:实现`IComparable`接口**
public class Person : IComparable
{
// ...其他代码...
public int CompareTo(Person other)
{
return this.Age.CompareTo(other.Age); // 按年龄升序
}
}
// 排序
Person[] people = new Person[]
{
new Person("张三", 25),
new Person("李四", 20)
};
Array.Sort(people); // 输出:李四, 20岁;张三, 25岁
**方式2:使用`Comparison
Array.Sort(people, (x, y) => x.Name.CompareTo(y.Name)); // 按姓名升序
#### 2.2 搜索:`Array.BinarySearch()`
二分查找要求数组已排序。返回元素索引,未找到则返回负数。
Array.Sort(people, (x, y) => x.Age.CompareTo(y.Age));
int index = Array.BinarySearch(people, new Person("李四", 20));
Console.WriteLine(index >= 0 ? $"找到:{people[index]}" : "未找到");
#### 2.3 扩容与复制:`Array.Resize()`和`Array.Copy()`
**动态扩容**:`Array.Resize()`创建新数组并复制原数据。
Person[] original = new Person[2];
Array.Resize(ref original, 4); // 扩容至4
**数组复制**:`Array.Copy()`按字节或元素复制。
Person[] source = { new Person("A", 10) };
Person[] destination = new Person[2];
Array.Copy(source, destination, source.Length); // 复制第一个元素
#### 2.4 其他实用方法
**反转数组**:`Array.Reverse()`
Array.Reverse(people);
**转换为列表**:`Array.AsList()`(需通过`ToList()`扩展方法)
using System.Linq;
List list = people.ToList();
三、实际应用场景
#### 3.1 数据处理与统计
统计自定义类型数组中满足条件的元素数量:
int count = people.Count(p => p.Age > 30);
Console.WriteLine($"年龄大于30的人数:{count}");
#### 3.2 多维数组与锯齿数组
**二维数组**:存储表格数据。
Person[,] matrix = new Person[2, 2]
{
{ new Person("A", 20), new Person("B", 21) },
{ new Person("C", 22), new Person("D", 23) }
};
**锯齿数组**:每行长度不同。
Person[][] jagged = new Person[2][]
{
new Person[] { new Person("X", 30) },
new Person[] { new Person("Y", 31), new Person("Z", 32) }
};
#### 3.3 性能优化:`ArrayPool`共享池
高频创建/销毁数组时,使用`ArrayPool
var pool = ArrayPool.Shared;
Person[] rented = pool.Rent(100); // 租用长度为100的数组
try
{
// 使用数组...
}
finally
{
pool.Return(rented); // 归还数组
}
四、常见问题与解决方案
#### 4.1 空引用异常(NullReferenceException)
访问未初始化的数组元素会抛出异常。解决方案:
if (people != null && people.Length > 0)
{
Console.WriteLine(people[0]);
}
#### 4.2 索引越界(IndexOutOfRangeException)
确保索引在`[0, Length-1]`范围内:
for (int i = 0; i
#### 4.3 排序不稳定问题
自定义比较逻辑时,确保符合业务需求。例如,按姓名排序时处理大小写:
Array.Sort(people, (x, y) =>
string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase));
五、总结与扩展
自定义类型数组与`Array`类的结合使用,能高效处理复杂数据。掌握以下要点:
- 自定义类型的声明与初始化方式。
- `Array`类的排序、搜索、复制等核心方法。
- 多维数组与锯齿数组的适用场景。
- 性能优化技巧(如`ArrayPool`)。
进一步学习可探索:
- `List
`与数组的对比选择。 - 并行处理数组(`Parallel.For`)。
- 不安全代码中的指针操作数组。
关键词:C#自定义类型数组、Array类、排序算法、数组扩容、多维数组、ArrayPool、索引越界、IComparable接口
简介:本文详细讲解C#中自定义类型数组的声明、初始化与基本操作,结合Array类的排序、搜索、复制等核心功能,通过代码示例展示实际应用场景,并分析常见问题与性能优化技巧,适合C#开发者深入掌握数组的高级用法。