C# 数组、索引器与集合介绍
.NET学习资料
.NET学习资料
.NET学习资料
在 C# 编程中,数组、索引器与集合是常用的数据结构,它们各自有着独特的功能和用途。
一、C# 数组
数组是一种用于存储固定数量同类型元素的数据结构。在 C# 中,数组的声明方式较为特殊,方括号必须紧跟在数据类型之后,例如int[] arr1; ,而不能写成int arr2[]; 这种在 Java 中允许的形式。
声明数组后,需要使用new关键字来分配内存空间,确定数组的大小。例如arr = new int[5]; ,这样就创建了一个包含 5 个整数元素的数组。C# 数组的索引从 0 开始,访问数组元素时,可通过索引值进行操作,如System.Console.WriteLine(arr[4]); 即可访问上述数组中的最后一个元素。
数组元素的初始化有多种方式。可以在创建时直接初始化,如int[] arr2Lines = new int[] {1, 2, 3, 4, 5}; ,也可以使用简化语法int[] arr1Line = {1, 2, 3, 4, 5}; ,此时数组大小会根据初始值设定项的数目自动确定。另外,还能在程序循环中使用for循环进行初始化,比如int[] TaxRates = new int[10]; for (int i = 0; i < TaxRates.Length; i++) { TaxRates[i] = 0; } 。
除了一维数组,C# 还支持交错数组和多维数组。交错数组是指每一行包含的列数不同的数组,例如int[][] jaggedArray = new int[2][]; jaggedArray[0] = new int[4];
jaggedArray[1] = new int[3]; 。多维数组类似于同类型值的矩阵,声明多维矩形数组的语法为int[,] arr2D; ,分配内存后,可通过双索引访问元素,如arr2D[4, 3] = 906; 。
二、C# 索引器
索引器是 C# 中的一种特殊属性,主要用于自定义集合类或数据结构中,允许开发者以类似数组的方式访问和操作集合内的元素 ,从而提供更加方便和灵活的访问方式。
常见的使用场景包括:
自定义集合类:若创建自定义的集合类,可利用索引器让用户通过索引获取和设置集合中的元素。例如创建一个自定义的List类,使用索引器实现通过索引值访问列表元素。
数据结构:在自定义的数据结构,如栈、队列、链表等中使用索引器,能方便地访问和操作数据结构中的节点或元素,提供直观简洁的编码方式。
代理类:某些情况下,索引器可用于实现代理类,通过索引访问和操作其他对象的属性或方法。
例如,定义一个包含索引器的MyCollection类:
class MyCollection
{
private string[] data;
public MyCollection()
{
data = new string[10];
}
// 索引器
public string this[int index]
{
get { return data[index]; }
set { data[index] = value; }
}
}
class Program
{
static void Main(string[] args)
{
MyCollection collection = new MyCollection();
collection[0] = "Hello";
collection[1] = "World";
Console.WriteLine(collection[0]); // 输出:Hello
Console.WriteLine(collection[1]); // 输出:World
}
}
在上述示例中,MyCollection类内部使用字符串数组data存储数据,定义的索引器this(int index)可通过索引获取或设置data数组中的元素。
索引器的特点包括:
可以有一个或多个参数,参数类型可以是任何合法的 C# 类型,如整数、字符串等。
可以有不同的访问修饰符,如public、private、protected等。
必须有一个返回类型,通常返回与参数类型相关的值。
名称必须是this,表示索引器所属的实例。
可以有get和set访问器,分别用于获取和设置索引的值。
使用索引器的优点有简化代码、提供更直观的访问方式、可自定义访问方式、提高代码的可维护性以及支持多个索引器。不过,索引器也存在一些缺点,如无法重载、无法指定可选参数、不支持可变参数、不支持重载运算符以及存在访问性限制等。
三、C# 集合
集合是.NET 提供的一种数据类型,类似于数组,是一组组合在一起的类型化对象,可通过遍历获取其中的每个元素。与数组不同的是,集合的存储空间是动态变化的,能够对其中的数据进行添加、删除、修改等操作。
集合需要使用System.Collections命名空间的集合接口来实现,该命名空间提供了许多常用接口:
ICollection:定义所有非泛型集合的大小、枚举数和同步方法。
Icomparer:公开一种比较两个对象的方法。
IDictionary:表示键 / 值对的非通用集合。
IDictionaryEnumerator:枚举非泛型字典的元素。
IEnumerable:公开枚举数,支持在非泛型集合上进行简单迭代。
IEnumerator:支持对非泛型集合的简单迭代。
IList:表示可按照索引单独访问得对象的非泛型集合。
(一)IEnumerable 和 IEnumerator 接口
IEnumerable接口用于公开枚举数,支持在非泛型集合上进行简单迭代,其包含一个GetEnumerator()方法,用于返回循环访问集合的枚举器。在实现IEnumerable接口时,通常还需要实现IEnumerator接口。IEnumerator接口支持对非泛型集合的简单迭代,包括Current属性、MoveNext()方法和Reset()方法 。
例如,通过继承IEnumerable和IEnumerator接口来定义一个集合存储商品信息,并遍历输出:
// 集合
using System.Collections;
namespace _06
{
public class Goods //定义集合中的元素类,表示商品信息类
{
public string Code { get; set; }
public string Name { get; set; }
public Goods(string code, string name)
{
Code = code;
Name = name;
}
}
public class JHClass : IEnumerable, IEnumerator //定义集合类
{
private readonly Goods[] _goods;
public JHClass(Goods[] gArray)
{
_goods = new Goods[gArray.Length];
for (int i = 0; i < gArray.Length; i++)
{
_goods[i] = gArray[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)this;
}
int position = -1;
object IEnumerator.Current
{
get { return _goods[position]; }
}
public bool MoveNext()
{
position++;
return (position < _goods.Length);
}
public void Reset()
{
position = -1;
}
}
class Program
{
static void Main()
{
Goods[] goodsArray = {
new Goods("T0001", "HuaWei MateBook"),
new Goods("T0002", "荣耀V30 5G"),
new Goods("T0003", "华为平板电脑")
};
JHClass jhList = new JHClass(goodsArray);
foreach (Goods g in jhList)
{
Console.WriteLine(g.Code + " " + g.Name);
}
Console.ReadLine();
}
}
}
(二)List 和 IList
List是一个具体的类,表示可以由索引访问的对象的列表;而IList是一个接口,表示可以由索引访问的对象的集合 。IList接口由ICollection和IEnumerable接口实现。
例如:
// IList接口及与List的比较
namespace _IList
{
class IList_Program
{
static void Main(string[] args)
{
IList<string> ilist = new List<string> { "Mark", "John" };
List<string> list = new List<string>();
list.Add("Mark");
list.Add("John");
foreach (string lst in list)
{
Console.WriteLine(lst);
}
Console.WriteLine();
Console.WriteLine("---对比---");
Console.WriteLine();
foreach (string lst in ilist)
{
Console.WriteLine(lst);
}
Console.ReadLine();
}
}
}
数组适用于存储固定数量且大小不变的数据;索引器为自定义集合类和数据结构提供了便捷的访问方式;集合则在需要动态管理数据时发挥重要作用。在实际编程中,应根据具体需求选择合适的数据结构来提高程序的效率和可读性。