索引器⚓︎
一、索引器概述⚓︎
索引器是类的特殊成员,索引器的存在允许类或结构体可以像数组一样进行索引。如:
数组的索引:
索引器:
SomeObject someObject = new SomeObject();
someObject["key"] = item; // 通过索引为某个对象的属性赋值
var item = someObject["key"]; // 通过索引获取某个对象的属性值
二、索引器的定义与调用⚓︎
01 定义索引器⚓︎
索引器使用 this
关键字定义,索引器与属性类似,在定义索引器时同样会用到 get 和 set 访问器,不同的是,访问属性不需要提供参数,而访问索引器则需要提供相应的参数。
通过访问器可以设置不同的索引器:读写索引器、只读索引器、只写索引器。
索引器定义示例1
class IndexerTest
{
private string[] arr = new string[100];
// 定义索引器
public string this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
// 主程序
class Program
{
static void Main()
{
var indexerTest = new IndexerTest();
indexerTest[0] = "Hello, World";
Console.WriteLine(indexerTest[0]);// 通过索引器访问属性
}
}
// The example displays the following output:
// Hello, World.
索引器定义示例2
internal class Person
{
private string name;
private int age;
public string this[int index]
{
get
{
switch (index)
{
case 0:
return name;
case 1:
return age.ToString();
default:
return "-1";
}
}
set
{
switch (index)
{
case 0:
name = value;
break;
case 1:
age = Int32.Parse(value);
break;
default:
throw new ArgumentOutOfRangeException("index error");
}
}
}
public void Speak()
{
Console.WriteLine("{0},{1}岁", this[0], this[1]);
}
}
// 主程序
internal class Program
{
private static void Main(string[] args)
{
Person p = new Person();
p[0] = "Tom";
p[1] = Convert.ToString(18);
p.Speak();
}
}
Note
- 索引器不必根据整数值进行索引,由你决定如何定义特定的查找机制。
- 索引器是实例成员,且索引器可被重载。
- 索引器可以有多个形参,例如当访问二维数组时。
- 通过在对象自身上使用数组表示法,允许访问对象内部集合的元素。
02 表达式主体⚓︎
索引器的 get 或 set 访问器包含一个用于返回或设置值的语句很常见。为了支持这种情况,表达式主体成员提供了一种经过简化的语法。
表达式主体简化索引器定义
class IndexerTest
{
private string[] arr = new string[100];
// 定义读写索引器,表达式主体
public string this[int i]
{
get => arr[i];
set => arr[i] = value;
}
}
class Program
{
static void Main()
{
var indexerTest = new IndexerTest();
indexerTest[0] = "Hello, World";
Console.WriteLine(indexerTest[0]);// 通过索引器访问属性
}
}
// The example displays the following output:
// Hello, World.
三、索引器重载⚓︎
索引器可以被重载,下面以上述示例2中的例子进行重载示范:
索引器重载
internal class Person
{
private string name;
private int age;
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
// 索引器
public int this[int index]
{
get => age;
set => age = value;
}
// 重载的索引器
public string this[string index]
{
get => name;
set => name = value;
}
public void Speak()
{
// 调用重载的索引器
Console.WriteLine("{0},{1}岁", this["name"], this[0]);
}
}
internal class IndexerOverload
{
private static void Main(string[] args)
{
Person person = new Person("tom", 18);
person.Speak();
}
}
// Output:
// tom,18岁
四、接口中的索引器⚓︎
接口中也可以定义索引,但与类中的索引器略有不同:
- 接口 get/set 访问器不使用修饰符;
- 接口 get/set 访问器通常没有正文.
示例: