索引器是一个我们经常打交道的特性,在编程过程中,多多少少都会用到索引器。而关于索引器一些高级话题,如给自定义的类添加索引器等也是本文着重介绍的。索引器本质上是一组get和set访问器, []中提供的是get访问器查找元素所要的参数,以及查找set访问器所要设置的元素时使用的参数。一个类或结构中只能有一个索引器且名称只能为this(但是索引器可以重载,重载方法就是提供不同类型的索引参数,这也是特别值得注意的是一点,索引器可以有多个索引参数,即下面语法结构的[]中可以提供多个参数(当然这样使用索引器时也要提供相应数量的参数))。
索引器的语法结构
public type this[type index]
{
get
{
GetAccessor
}
set
{
SetAccessor
}
}
第一个type是索引器(返回值)的类型,正如定义属性中的类型。而第二个type是索引的类型。类似于属性,定义的索引器也不会被分配命名空间,且get,set可以只实现一个或者都实现,但属性通常用于访问单个数据成员,索引用于访问多个数据成员。
在索引器中应该对索引器进行范围检查防止出现异常。另外不可以声明static的索引器。示例:下列自定义类型提供了一个索引器以使我们用更方便的方法来操作整型中的位。
structIntBits
{
public IntBits(int initialBitValue)
{
bits = initialBitValue;
}
private int bits;
public bool this[int index]
{
get
{
return (bits & (1 << index)) != 0;
}
set
{
//如果value为true,就开启比特,否则把它关闭
if (value)
bits |= (1 << index);
else
bits &= -(1 << index);
}
}
}
这个类的使用方式:
int adapted = 63;
IntBits bits = new IntBits(adapted);
//获取索引位置6的bool值
bool peek = bits[6];
//将索引0的比特设为true
bits[0] = true;
//将索引31的比特设为false
bits[31] = false;
索引器的下标可以是字符串等非整数。索引器不可以作为ref或者out参数。
下面再提供另一个索引器定义的示例:
classEmployee
{
public string LastName;
public string FirstName;
public string CityOfBirth;
public string this[int index]
{
set
{
switch (index)
{
case 0:
LastName = value;
break;
case 1:
FirstName = value;
break;
case 2:
CityOfBirth = value;
break;
default:
throw new ArgumentOutOfRangeException("index");
}
}
get
{
switch (index)
{
case 0:
return LastName;
case 1:
return FirstName;
case 2:
return CityOfBirth;
default:
throw new ArgumentOutOfRangeException("index");
}
}
}
}
下面的代码展示了索引器重载的代码结构:
classMyClass
{
public string this[int index]
{
set { … }
get { … }
}
public string this[int index1, int index2]
{
set { … }
get { … }
}
public string this[float index]
{
set { … }
get { … }
}
}
索引器中访问器的访问修饰符与属性访问器的遵守一致的规则:
Ø 当属性或索引既有get访问器也有set访问器时才能给访问器添加访问修饰符。
Ø 只能给两个访问器中的一个添加访问修饰符。
Ø 访问器的修饰符需要比成员的访问级别有更严格的限制。
另外,像是HashTable等字典类内部使用了索引器,从而可以使下列代码1用代码2这种更易懂的方式来表示:
方式1:
Hashtable