第16章 索引器.docx
《第16章 索引器.docx》由会员分享,可在线阅读,更多相关《第16章 索引器.docx(20页珍藏版)》请在冰点文库上搜索。
第16章索引器
第16章索引器
目标
学习完本章之后,你应该能够掌握以下概念:
Ø什么是索引器
Ø如何定义和使用索引器
Ø索引器和属性的区别
Ø如何为接口创建索引器
Ø使用索引器的目的
Ø如何创建只读索引器
Ø如何为结构创建索引器
引言
索引器允许类或结构的实例按照与数组相同的方式进行索引。
索引器类似于属性,不同之处在于索引器的访问器采用参数。
本章将介绍索引器在类、结构以及接口中的应用。
16.1索引器
16.1.1什么是索引器
可以将索引器理解为一种属性,但是其特性与一般属性并不相同。
首先其访问器即get代码块采用参数,另外其作用也不相同。
索引器可以为类提供类似数组索引的访问方式。
索引器有以下特点:
Ø索引器使得对象可按照与数组相似的方法进行索引。
Øget访问器返回值,set访问器分配值。
Øthis关键字用于定义索引器。
Øvalue关键字用于定义由set索引器分配的值。
Ø索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。
Ø索引器可被重载。
Ø索引器可以有多个形参,例如当访问二维数组时。
16.1.2索引器的目的
索引器的目的在于为类提供与数组相似的方法进行索引。
这里读者可以先回忆一下数组的使用方式,定义一个数组后,便可以方便地对数组中特定位置的元素进行访问或设置。
如下代码演示了一个最简单的数组及其使用方法:
。
usingSystem.Text;
namespaceExample16_1
{
classProgram
{
staticvoidMain(string[]args)
{
//定义一个大小为100的整型数组
int[]intArray=newint[100];
//分别为数组中的每个元素赋值
for(inti=0;i<100;i++)
{
intArray[i]=i*5;
}
//输出intArray数组中所有元素的值
for(inti=0;i<100;i++)
{
Console.WriteLine(”intArray[{O}]的值为:
{1}”,i,i*5);
}
Console.ReadLine();
}
}
}
程序运行结果如下
intArray[O]的值为:
0
intArray[1]的值为:
5
intArray[2]的值为:
10
intArray[3]的值为:
15
intArray[4]的值为:
20
intArray[5]的值为:
25
intArray[6]的值为:
30
intArray[7]的值为:
35
intArray[8]的值为:
40
intArray[9]的值为:
45
intArray[10]的值为:
50
intArray[1l]的值为:
55
intArray[12]的值为:
60
intArray[13]的值为:
65
intArray[14]的值为:
70
intArray15]的值为:
75
intArray[16]的值为:
80
这里只显示了一部分结果,结果最后的省略号并非程序输出。
16.1.3定义索引器
索引器的定义非常简单,如下的代码段就定义了一个简单的索引器
C1assIntSet
{
//定义一个大小为100的整型数组
int[]intArray=newint[100];
///</summary>
///索引</param>
///intArray的相应值</returns>
publicintthis[inti]
{
get
{
returnintArray[i];
}
set
{
intArray[i]=value;
)
)
索引器的定义采用访问限定符后跟返回值类型、this关键字、索引参数。
其中,索引参数要包含在索引操作符“[]”中。
索引器的使用参见下面的小节。
16.1.4使用索引器
索引器的使用比较简单,只需在对象名后加索引操作符和索引即可。
下面的实例演示了类
中索引器的用法:
namespaceExample16_2
{
classProgram
{
staticvoidMain(String[]args)
{
//定义一个IntSet类型对象,并为其中部分值赋值。
IntSetmyIntSet=newIntSet();
for(inti=0;i<10;i++)
{
myIntSet[i*10]=i*4;
)
//输出已经改变的值
for(inti=0;i<10;i++)
{
Console.WriteLine("myIntSet[{O}]的值:
{l}”,i*10,myIntSet[i*10]);
)
//输出部分未改变的值
Console.WriteLine("myIntSet[{O)]的值为:
{1)”,1,myIntSet[1]);
Console.WriteLine("myIntSet[{O}]的1直为:
{1)”,12,myIntSet[12]);
ConSole.ReadLine();
}
}
///
///演示索引器使用方法的整数集合类
///</summary>
C1assIntSet
{
///
///构造函数
///</summary>
publicIntSet()
{
//分别为数组中的每个元素赋值0
for(inti=0;i<100;i++)
{
intArray[i]=0;
}
}
//定义一个大小为100的整型数组
int[]intArray=newint[100];
///
///类IntSet的索引器
///</summary>
///索引</param>
///intArray的相应值</returns>
publicintthis[inti]
{
get
{
returnintArray[i];
}
set
{
intArray[i]=value;
)
}
}
}
可以看到,实例中通过索引器的方法为数组中所有10的倍数位置的元素进行了赋值操作,后又通过索引器的方法访问并输出其元素的值。
其结果比较明显。
索引器的应用并不仅仅限于这种简单的数据类型,如整数。
如可以定义一个班级类,通过班级类的索引器可以返回班级中的学生。
下面的实例简单实现了上段的描述:
USingSyStem;
USingSystem.Collections.Generic;
USingSystem.Text;
namespaceExample16_3
{
classProgram
{
staticvoidMain(String[]args)
{
ClassmyClass=newClass(”一年级一班”);
//为班级中学生的姓名赋值
myClasS[0].Name=”Liu”;
myClass[1].Name=”Wang”;
myClasS[2].Name=”Li”;
myClaSS[3].Name=”Zhang”;
myClass[4].Name=”Wu”;
myClass[5].Name=”Zhao”;
myClaSS[6】.Name=”Mu”;
myClass[7].Name=”Yuan”;
myClass[8].Name=”Lei”;
myClass[9].Name="Sun";
//输出班级中的所有学生
for(inti=0;i<10;i++)
{
Console.WriteLine("{O}的{1}号学生的姓名为:
{2}”,myClass.Name,i,myClass[i].Name);
}
Console.ReadLine();
}
}
///
///一个学生类的简单实现。
///</summary>
classStudent
{
publicStudent(stringname,intnumber)
{
//初始化学生的姓名和学号
m_name=name;
m_number=number;
}
privatestringm_name=string.Empty;
privateintm_number=0;
publicstringName
{
get
{
returnm_name;
)
set
{
m_name。
value;
}
}
publicintNumber
{
get
{
returnm_number;
}
set
{
m_number=value;
)
)
classC1ass
{
publicClass(stringname)
{
//初始化相应的参数
m_name=name;
for(inti=0;i<10;i++)
{
students[i]=newStudent(i.ToString(),i);
}
}
privateStringm_name;
privateStudent[]students=newStudent[10];
publicstringName
{
get
{
returnm_name;
}
set
{
m_name=value;
}
}
publicStudentthis[inti]
{
get
{
returnstudents[i];
}
set
{
students[i]=value;
)
}
}
)
程序运行结果如下:
一年级一班的0号学生的姓名为:
Liu
一年级一班的1号学生的姓名为:
Wang
一年级一班的2号学生的姓名为:
Li
一年级一班的3号学生的姓名为:
Zhang
一年级一班的4号学生的姓名为:
Wu
一年级一班的5号学生的姓名为:
Zhao
一年级一班的6号学生的姓名为:
Mu
一年级一班的7号学生的姓名为:
Yuan
一年级一班的8号学生的姓名为:
Lei
一年级一班的9号学生的姓名为:
Sun
上面演示了一个相对比较复杂的实例,但仍与真实项目中的建模有相当的差距。
阅读上面的实例时,读者只需把握这样一种关系,即班级由学生构成,学生有姓名和学号这两种属性。
实例就是通过索引器的方式访问班级中的学生。
16.1.5只读索引器
与属性一样,索引器也可以设计为只读。
只需放弃索引器中set代码块的编写即可。
下面的代码实现了一个简单的索引器,该索引器为只读:
classIntSet
{
publicIntSet()
{
//分别为数组中的每个元素赋值0
for(inti=0;i<100;i++)
{
intArray[i]=0;
)
}
int[]intArray=newint[100];
publicintthis[inti]
{
get
{
returnintArray[i];
)
)
}
其使用方法与只读属性相同,不能对其进行赋值操作,否则将会引发错误。
16.2其他结构中的索引器
索引器不仅存在于类中,C#中其他的结构也可以使用索引器,如结构和接口。
本节介绍索引器在结构和接13中的使用方法。
16.2.1结构中的索引器
同类一样,结构中也可以使用索引器。
但在使用时要注意结合结构自身的特点进行设计。
下面的实例演示了在结构中使用索引器的方法:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample16_4
{.
classProgram
{
staticvoidMain(string[]args)
{
//定义一个IntStruct类型对象,并为其中部分值赋值。
IntStructmyIntStruct=newIntStruct(100)j
for(inti=0;i<10;i++)
{
myIntStruct[i*10]=i;
}
//输出已经改变的值
for(inti=0;i<10;i++)
{
Console.WriteLine(”myIntStruct[{O}]的值为:
{1)”,i*10,
myIntStruct[i*10]);
)
//输出部分未改变的值
Console.WriteLine("myIntStruct[{0}]的值为:
{l}",1,myIntStruct[1]);
Console.WriteLine("myIntStruct~{0)]的值为:
{1}",12,myIntStruct[12]);
Conso1e.ReadLine();
}
}
StructIntStruct
{
///
///构造函数
///</summary>
publicIntStruct(intsize)
{
intArray=newint[size];
//分别为数组中的每个元素赋值0
for(inti=0;i{
intArray[i]=0;
)
//定义一个大小为100的整型数组
int[]intArray;
///
///类IntSet的索;】器
///</summary>
///索引</param>
///intArray的相应值</returns>
publicintthis[inti]
{
get
{
returnintArray[i];
)
set
{
intArray[i]=value;
}
}
}
}
程序运行结果如下
myIntStruct[O]的值为:
0
myIntStruct[10]的值为:
1
myIntStruct[20]的值为:
2
myIntStruct[30]的值为:
3
myIntStruct[40]的值为:
4
myIntStruct[50]的值为:
5
myIntStruct[60]的值为:
6
myIntStruct[70]的值为:
7
myIntStruct[80]的值为:
8
myIntStruct[90]的值为:
9
myIntStruct[1]的值为:
0
myIntStruct[12]的值为:
0
可以看到,其使用方式与在类中使用索引器基本相同。
此处就不赘述了,读者可以根据项目的实际情况选择使用类或者结构。
16.2.2接口中的索引器
同类和结构一样,接口中也可以定义索引器。
在进行建模设计时,可以通过在接口中定义索引器的办法,使得继承该接口的类都必须提供相应的索引器。
下面的实例演示了在接口中定义索引器的办法:
publicinterfaceIMyInterface
{
intthis[intindex]
{
get;
set;
}
}
如此便在接在IMyInterface中定义了一个索引器。
下面对前文中的班级学生实例进行修改,定义一个IClass接口,在接口中定义索引器,使得Class类实现IClass中的定义。
将前文实例中Class类的实现代码替换为如下代码即可:
///
///IClass接口
///</summary>
interfaceIClass
{
///
///索引器
///</summary>
///索引</param>
///相应学生</returns>
Studentthis[inti]
{
get;
set;
}
///
///班级类的简单实现
///</summary>
classC1ass:
IClass
{
///
///班级类的构造函数
///
///班级名称</param>
publicClass(stringname)
{
//初始化相应的参数
m_name=name;
for(inti=0;i<10;i++)
{
students[i]=newStudent(i.ToString(),i);
)
}
///
///班级名称字段
///</summary>
privatestringm_name;
///
///所有学生的集合
///</summary>
privateStudent[]students=newStudent[10];
///
///班级名称属性
///</summary>
publicstringName
{
get
{
returnm_name;
)
set
{
m_name=value;
)
)
///
///班级的索引器,用于访问班级的学生
///</summary>
///索引</param>
///相应的学生对象</returns>
publicStudentthis[inti]
{
get
{
returnstudents[i];
}
Set
{Students[i]=value;
)
)
)
可以看到,在接口中使用索引器也非常简单。
16.2.3小结
本章介绍了C#中的一个重要功能,即索引器。
索引器和委托都是C#中与其他语言不同的地方,有其他编程语言经验的读者可能对此不太熟悉。
但正是这些不同之处在学习时需要重点掌握。
索引器的合理使用可以给编程带来很大的方便,相信通过本章的学习读者已经感受到了这种方便。
希望读者能熟练掌握C#的这些独特知识点。