C# - 索引器
索引器 允许对象像数组一样被索引。当你为一个 class 定义索引器时,这个 class 的行为类似于一个 虚拟数组。然后,你可以使用数组访问操作符 ([ ]) 来访问这个 class 的实例。
语法
以下是一维索引器的语法 −
element-type this[int index] {
// get 访问器。
get {
// 返回由 index 指定的值
}
// set 访问器。
set {
// 设置由 index 指定的值
}
}
索引器的使用
索引器的声明行为在某种程度上类似于 property。与 property 类似,你使用 get 和 set 访问器来定义索引器。然而,property 返回或设置特定的数据成员,而索引器从对象实例中返回或设置特定的值。换句话说,它将实例数据分解成更小的部分,并对每个部分进行索引,获取或设置每个部分。
定义 property 需要提供 property 名称。索引器不是用名称定义的,而是使用 this 关键字,它引用对象实例。
示例
在这个示例中,我们演示了索引器,允许 IndexedNames class 的对象像数组一样被访问,用于存储和检索名称 −
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();
}
}
}
当上述代码被编译并执行时,会产生以下结果 −
Zara Riz Nuha Asif Davinder Sunil Rubic N. A. N. A. N. A.
定义索引器
你可以使用 "this" 关键字后跟方括号内的参数列表来定义索引器。请注意 - 索引器必须包含 get 和/或 set 访问器来检索或赋值值。
示例
在以下示例中,我们定义了一个索引器,使用数组语法在内部数组中存储和检索整数值 −
using System;
class SampleCollection
{
private int[] arr = new int[5];
public int this[int index]
{
get { return arr[index]; }
set { arr[index] = value; }
}
}
class Program
{
static void Main()
{
SampleCollection sc = new SampleCollection();
sc[0] = 10;
sc[1] = 20;
Console.WriteLine("Value at index 0: " + sc[0]);
Console.WriteLine("Value at index 1: " + sc[1]);
}
}
当上述代码被编译并执行时,会产生以下结果 −
Value at index 0: 10 Value at index 1: 20
使用字符串键的索引器(Dictionary 风格)
你可以像字典一样定义索引器,使用字符串作为键。这种定义方式在你希望使用字符串标识符来检索或赋值时非常有用。
示例
在下面的示例中,我们使用字符串索引器来访问和存储类似字典的结构中的值 −
using System;
using System.Collections.Generic;
class Contacts
{
private Dictionary<string, string> phoneBook = new Dictionary<string, string>();
public string this[string name]
{
get { return phoneBook.ContainsKey(name) ? phoneBook[name] : "Not Found"; }
set { phoneBook[name] = value; }
}
}
class Program
{
static void Main()
{
Contacts c = new Contacts();
c["Aman"] = "1234567890";
c["Ravi"] = "9876543210";
Console.WriteLine("Aman's Number: " + c["Aman"]);
Console.WriteLine("Ravi's Number: " + c["Ravi"]);
Console.WriteLine("Unknown: " + c["Unknown"]);
}
}
当上述代码编译并执行时,会产生以下结果 −
Aman's Number: 1234567890 Ravi's Number: 9876543210 Unknown: Not Found
带有访问修饰符的索引器
你也可以使用访问修饰符为索引器的 get 和 set 访问器指定不同的访问级别。
示例
在下面的示例中,set 访问器是 private 的,因此索引器的值只能在类内部设置 −
using System;
class MyCollection
{
private string[] items = new string[3] { "One", "Two", "Three" };
public string this[int index]
{
get { return items[index]; }
private set { items[index] = value; }
}
public void UpdateItem(int index, string newValue)
{
this[index] = newValue;
}
}
class Program
{
static void Main()
{
MyCollection col = new MyCollection();
Console.WriteLine("Before: " + col[1]);
col.UpdateItem(1, "Updated");
Console.WriteLine("After: " + col[1]);
}
}
当上述代码编译并执行时,会产生以下结果 −
Before: Two After: Updated
重载索引器
索引器可以被重载。索引器也可以使用多个参数声明,每个参数可以是不同的类型。索引不必一定是整数。C# 允许索引器使用其他类型,例如 string。
示例
这是索引器的另一个示例。在此,我们演示重载索引器 −
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();
}
}
}
上述代码编译并执行后,将产生以下结果 −
Zara Riz Nuha Asif Davinder Sunil Rubic N. A. N. A. N. A. 2