第4章:索引器


本章目标

  1. 了解索引器的原理

  2. 熟练使用索引器

本章内容

索引器的概念

​ 在 C# 中,索引器(Indexer)是一种特殊的属性,允许类的实例像数组一样通过索引访问。

​ 索引器允许通过类实例的索引来访问该类的实例成员。它的声明类似于属性,但具有参数。通常情况下,索引器用于允许类的实例像数组一样通过索引进行访问。

索引器的语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyClass
{
// 声明一个索引器
public returnType this[indexType index]
{
get
{
// 返回索引位置的值
}
set
{
// 设置索引位置的值
}
}
}

  • returnType: 索引器返回的数据类型,可以是任意有效的 C# 数据类型。
  • indexType: 索引的参数类型,可以是整数、字符串或其他合法类型。
  • get: 获取索引位置的值的访问器。
  • set: 设置索引位置的值的访问器。

索引器的特点

  • 使用索引器可以用类似于数组的方式为对象建立索引;
  • get访问器返回值,set访问器分配值;
  • this关键字用于定义索引器;
  • 索引器不必根据整数值进行索引,可以自定义查找机制;
  • 索引器可被重载;
  • 索引器可以有多个形参;
  • 索引器必须是实例成员

索引器的示例

定义索引器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>
/// 整型参数所引器
/// </summary>
class IndexClass<T>
{

T[] data = new T[10];

public T this[int index]
{
get
{
return data[index];
}
set
{
data[index] = value;
}
}
}

使用索引器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CH04Demo
{
internal class Program
{
static void Main(string[] args)
{
IndexClass<string> p = new IndexClass<string>();

//通过索引器的访问方式来赋值
p[0] = "张三";

Console.WriteLine(p[0]);

Console.ReadKey();
}
}
}

索引器进阶

多维索引器

C#索引器可以支持多维索引,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CH04Demo
{
internal class IndexClass2<T>
{

T[,] data = new T[5, 10];

public T this[int row, int col]
{
get
{
return data[row, col];
}
set
{
data[row, col] = value;
}
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CH04Demo
{
internal class Program
{
static void Main(string[] args)
{
IndexClass2<string> indexClass = new IndexClass2<string>();

indexClass[0, 0] = "张三";
indexClass[4, 9] = "李四";

Console.WriteLine(indexClass[0, 0]);
Console.WriteLine(indexClass[4, 9]);

Console.ReadKey();
}
}
}

索引器重载

C#允许对索引器进行重载,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CH04Demo
{
/// <summary>
/// 索引重载
/// </summary>
internal class IndexClass3
{
Hashtable table = new Hashtable();

/// <summary>
/// 字符串型索引
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public object this[string index]
{
get
{
return table[index];
}
set
{
table[index] = value;
}
}

/// <summary>
/// 整型索引
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public object this[int index]
{
get
{
return table[index];
}
set
{
table[index] = value;
}
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CH04Demo
{
internal class Program
{
static void Main(string[] args)
{
IndexClass3 indexClass=new IndexClass3();

//赋值
indexClass[1] = new Student { Name="孙悟空",Age=500};
indexClass["GCKJ101"] = new Student { Name = "太白金星", Age = 1500 };

//读取
Console.WriteLine(indexClass[1]);
Console.WriteLine(indexClass["GCKJ101"]);

Console.ReadKey();
}
}

class Student
{
public string Name { get; set; }

public int Age { get; set; }

public override string ToString()
{
return string.Format($"姓名:{this.Name},年龄:{this.Age}");
}
}
}

索引器的注意事项

  • 索引器可以具有多个参数,但每个参数的类型必须唯一。
  • 索引器的参数可以是值类型或引用类型。
  • 可以根据需要只声明 get 或 set 访问器,但至少必须实现其中一个。

本章总结

索引器是 C# 中一个强大且灵活的特性,允许类的实例像数组一样通过索引来访问。它提供了一种简洁、直观的方式来管理类的实例数据,特别适用于需要按照索引方式进行访问和修改的场景。

课后作业

1.定义类MyList1<T>,内部用List<T>存储数据,包含索引器this[int index]

2.定义类MyList2<K,V> ,内部使用Dictionary<k,v>存储数据,包含索引器this[k key]