本文档根据 C# 编程指南 改编而成。主要介绍以下内容。
使用索引器
接口中的索引器
属性与索引器区别
索引器
索引器允许类或结构的实例就像数组一样进行索引。 无需显式指定类型或实例成员,即可设置或检索索引值。 索引器类似于属性,不同之处在于它们的访问器需要使用参数。
- 使用索引器可以用类似于数组的方式为对象建立索引。
- get 取值函数返回值。 set 取值函数分配值。
- this 关键字用于定义索引器。
- value 关键字用于定义 set 索引器所赋的值。
- 索引器不必根据整数值进行索引;由你决定如何定义特定的查找机制。
- 索引器可被重载。
- 索引器可以有多个形参,例如当访问二维数组时。
使用索引器
索引器使你可从语法上方便地创建类、结构或接口,以便客户端应用程序能像访问数组一样访问它们。 在主要目标是封装内部集合或数组的类型中,常常要实现索引器。
示例
class TempRecord
{
// Array of temperature values
private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F,
61.3F, 65.9F, 62.1F, 59.2F, 57.5F };
// To enable client code to validate input
// when accessing your indexer.
public int Length
{
get { return temps.Length; }
}
// Indexer declaration.
// If index is out of range, the temps array will throw the exception.
public float this[int index]
{
get
{
return temps[index];
}
set
{
temps[index] = value;
}
}
}
class MainClass
{
static void Main()
{
TempRecord tempRecord = new TempRecord();
// Use the indexer's set accessor
tempRecord[3] = 58.3F;
tempRecord[5] = 60.1F;
// Use the indexer's get accessor
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, tempRecord[i]);
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
使用其他值进行索引
C# 不将索引参数类型限制为整数。
例如,对索引器使用字符串可能有用。 通过搜索集合内的字符串并返回相应的值,可以实现此类索引器。 由于访问器可被重载,字符串和整数版本可以共存。
接口中的索引器
可以在接口上声明索引器。 接口索引器的访问器与类索引器的访问器有所不同,差异如下:
- 接口访问器不使用修饰符。
- 接口访问器没有正文。
因此,访问器的用途是指示索引器为读写、只读还是只写。
下面是接口索引器访问器的示例:
// Indexer on an interface:
public interface ISomeInterface
{
// Indexer declaration:
int this[int index]
{
get;
set;
}
}
// Implementing the interface.
class IndexerClass : ISomeInterface
{
private int[] arr = new int[100];
public int this[int index] // indexer declaration
{
get
{
// The arr object will throw IndexOutOfRange exception.
return arr[index];
}
set
{
arr[index] = value;
}
}
}
class MainClass
{
static void Main()
{
IndexerClass test = new IndexerClass();
System.Random rand = new System.Random();
// Call the indexer to initialize its elements.
for (int i = 0; i < 10; i++)
{
test[i] = rand.Next();
}
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, test[i]);
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
注意:当类采用相同的索引签名实现多个接口时,需用完全限定名称以避免歧义
详情见示例
// Indexer on an interface:
public interface ISomeInterface
{
// Indexer declaration:
string this[int index]
{
get;
set;
}
}
public interface ICitizen
{
string this[int index]
{
get;
set;
}
}
// Implementing the interface.
class IndexerClass : ISomeInterface, ICitizen
{
private string[] arr = new string[100];
private string[] arr_str = new string[100];
string ICitizen.this[int index]
{
get
{
return arr_str[index];
}
set
{
arr_str[index] = value;
}
}
string ISomeInterface.this[int index]
{
get
{
// The arr object will throw IndexOutOfRange exception.
return arr[index];
}
set
{
arr[index] = value;
}
}
}
class MainClass
{
static void Main()
{
Console.WriteLine("ISomeInterface\n");
ISomeInterface test = new IndexerClass();
System.Random rand = new System.Random();
// Call the indexer to initialize its elements.
for (int i = 0; i < 10; i++)
{
test[i] = Convert.ToString(rand.Next());
}
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, test[i]);
}
Console.WriteLine("\nICitizen\n");
ICitizen cities = new IndexerClass();
System.Random rand1 = new System.Random();
// Call the indexer to initialize its elements.
for (int i = 0; i < 10; i++)
{
cities[i] = "hangzhou" + rand.Next();
}
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Element #{0} = {1}", i, cities[i]);
}
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
属性与索引器的区别
索引器与属性相似。
除下表所示的差别外,对属性访问器定义的所有规则也适用于索引器访问器。
Proprety | 索引器 |
---|---|
允许以将方法视作公共数据成员的方式调用方法。 | 通过在对象自身上使用数组表示法,允许访问对象内部集合的元素。 |
通过简单名称访问。 | 通过索引访问。 |
可为静态成员或实例成员。 | 必须是实例成员。 |
属性的 get 访问器没有任何参数。 | 索引器的 get 访问器具有与索引器相同的形参列表。 |
属性的 set 访问器包含隐式 value 参数。 | 索引器的 set 访问器具有与索引器相同的形参列表,value 参数也是如此。 |
通过自动实现的属性支持简短语法。 | 不支持简短语法。 |