文章目录
- 前言
- 一、索引器的语法规则
- 二、索引器的用途及与属性的对比
- 三、索引器的重载
前言
在 C# 编程中,索引器(Indexer)是一项极具特色且实用的语言特性,它赋予了对象一种独特的访问方式,使得对象能够如同数组一般,通过下标的形式来进行访问。当我们为一个类定义了索引器后,这个类在使用上就仿佛变成了一个虚拟数组(virtual array),能够借助数组访问运算符 “[]” 轻松地访问类中的成员,为代码的编写和数据的操作带来了极大的便利性和灵活性。
一、索引器的语法规则
一维索引器的语法结构如下所示:
element-type this[int index]
{
// get 访问器
get
{
// 返回 index 指定的值
}
// set 访问器
set
{
// 设置 index 指定的值
}
}
在这里,element-type 代表的是通过索引器访问时返回(或设置)的数据类型,this 关键字有着关键作用,它指向当前的对象实例,而 int index 则表示索引器所使用的索引参数,通常是整型,但其实也可以是其他类型(后续会讲到索引器的重载情况)。get 访问器用于获取指定索引位置对应的值,在其内部编写相应的逻辑来返回符合要求的数据;set 访问器则负责设置指定索引位置的值,比如将外部传入的值赋给对象内部相应的数据成员等操作。
二、索引器的用途及与属性的对比
与属性的相似性和区别
索引器的行为在声明方式上在某种程度上和属性(property)颇为相似,它们都可以使用 get 和 set 访问器来定义相关的访问逻辑。然而,二者之间又存在着明显的差异。属性主要是用于返回或设置一个特定的数据成员,比如类中的某个字段等;而索引器则是将对象实例的数据进一步细分,把实例数据分割成更小的部分,并且通过索引的方式对每个部分进行标记,从而能够方便地获取或设置这些细分后的每一部分数据。
另外,定义属性时需要明确提供属性的名称,而索引器在定义时并不带有常规意义上的名称,它依靠 this 关键字来关联到具体的对象实例,以此实现通过下标形式访问对象内部数据的功能。
以下通过一个实例可以清晰地展现索引器这一概念及其使用方式:
using System;
namespace IndexerApplication
{
class IndexedNames
{
private string[] namelist = new string[size];
static public int size = 10;
public IndexedNames()
{
for (int i = 0; i < size; i++)
namelist[i] = "N. A.";
}
public string this[int index]
{
get
{
string tmp;
if (index >= 0 && index <= size - 1)
{
tmp = namelist[index];
}
else
{
tmp = "";
}
return (tmp);
}
set
{
if (index >= 0 && index <= size - 1)
{
namelist[index] = value;
}
}
}
static void Main(string[] args)
{
IndexedNames names = new IndexedNames();
names[0] = "Zara";
names[1] = "Riz";
names[2] = "Nuha";
names[3] = "Asif";
names[4] = "Davinder";
names[5] = "Sunil";
names[6] = "Rubic";
for (int i = 0; i < IndexedNames.size; i++)
{
Console.WriteLine(names[i]);
}
Console.ReadKey();
}
}
}
在上述代码中,定义了 IndexedNames 类,其内部有一个字符串数组 namelist,并通过索引器 public string this[int index] 来实现对这个数组元素的访问控制。在 Main 方法中,先是通过索引器设置了数组中部分元素的值,然后再利用索引器循环获取并输出数组元素的值,当代码被编译和执行后,会按照设定输出相应的结果:
Zara
Riz
Nuha
Asif
Davinder
Sunil
Rubic
N. A.
N. A.
N. A.
三、索引器的重载
重载的概念与实现方式
索引器(Indexer)具备可重载的特性,这意味着在声明索引器的时候,可以带有多个参数,并且每个参数的类型也可以各不相同,并不局限于必须是整型。例如,C# 允许索引器的参数可以是字符串类型等其他数据类型,通过这种重载机制,能够为同一个类提供多种不同的索引访问方式,以满足多样化的使用场景需求。
以下的实例展示了索引器重载的具体应用:
using System;
namespace IndexerApplication
{
class IndexedNames
{
private string[] namelist = new string[size];
static public int size = 10;
public IndexedNames()
{
for (int i = 0; i < size; i++)
{
namelist[i] = "N. A.";
}
}
public string this[int index]
{
get
{
string tmp;
if (index >= 0 && index <= size - 1)
{
tmp = namelist[index];
}
else
{
tmp = "";
}
return (tmp);
}
set
{
if (index >= 0 && index <= size - 1)
{
namelist[index] = value;
}
}
}
public int this[string name]
{
get
{
int index = 0;
while (index < size)
{
if (namelist[index] == name)
{
return index;
}
index++;
}
return index;
}
}
static void Main(string[] args)
{
IndexedNames names = new IndexedNames();
names[0] = "Zara";
names[1] = "Riz";
names[2] = "Nuha";
names[3] = "Asif";
names[4] = "Davinder";
names[5] = "Sunil";
names[6] = "Rubic";
// 使用带有 int 参数的第一个索引器
for (int i = 0; i < IndexedNames.size; i++)
{
Console.WriteLine(names[i]);
}
// 使用带有 string 参数的第二个索引器
Console.WriteLine(names["Nuha"]);
Console.ReadKey();
}
}
}