索引器:是C#引入的一个新型的类成员,它允许类或结构的实例按照与数组相同的方式进行索引。
索引器类型于属性,它们的不同之处在于索引器的访问器采用参数。
定义了索引器之后,就可以像访问数组一样,使用[]运算符访问类的成员。
定义索引器的方式与定义属性有些类似,其一般形式如下:
[修饰符] 数据类型 this <[数据类型 标识符]>
{
get{//获得属性的代码}
set{//设置属性的代码}
}
索引器概述:
使用索引器可以用类似于数组的方式为对象建立索引。
get accessor returns a value." data-guid="5e97def07fe15e931d526cafa5b97644">get 访问器返回值。 set accessor assigns a value." data-guid="66b9797a805b510e697d60c805140aeb">set 访问器分配值。
this keyword is used to define the indexers." data-guid="c34f23e68daf270013978542591de397">this 关键字用于定义索引器。
value keyword is used to define the value being assigned by the set indexer." data-guid="599578d2a780928307c04f6ca2b0f058">value 关键字用于定义由 set 索引器分配的值。
索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。
索引器可被重载。
索引器可以有多个形参,例如当访问二维数组时。
属性与索引器的比较:
属性 | 索引器 |
允许像调用公共数据成员一样调用方法 | 允许对一个对象本身使用数组表示法来访问该对象内部集合中的元素 |
可通过简单的名称进行访问 | 可通过索引器进行访问 |
可以为静态成员或实例成员 | 必须为实例成员 |
get accessor of a property has no parameters." data-guid="a6cc8a328d7d6f37fe6726bef0a1e49b">属性的 get 访问器没有参数 | get accessor of an indexer has the same formal parameter list as the indexer." data-guid="d83df23e86b78dbdb4847d31d82a2337">索引器的 get 访问器具有与索引器相同的形参表 |
set accessor of a property contains the implicit value parameter." data-guid="7b8d943b10ea3a65d99f8a3c0b284e05">属性的 set 访问器包含隐式 value 参数 | set accessor of an indexer has the same formal parameter list as the indexer, and also to the value parameter." data-guid="61fa719a7490fc5fb284c6b5ef3c3c36">除了值参数外,索引器的 set 访问器还具有与索引器相同的形参表 |
Auto-Implemented Properties (C# Programming Guide)." data-guid="0980783e25d81c644f0194104a5b78f1">支持对自动实现的属性(C# 编程指南)使用短语法 | 不支持短语法 |
get and set accessor methods as a means of assigning and retrieving values." data-guid="dd23dc3354d63d8f7d007da64625c804"> 在下面的示例中,定义了一个泛型类,并为其提供了简单的 get 和 set 访问器方法(作为分配和检索值的方法)。 Program class creates an instance of this class for storing strings." data-guid="6ddaa503e5fad577a85f10e9f502a5c1">Program 类为存储字符串创建了此类的一个实例。
class SampleCollection<T> { // Declare an array to store the data elements. private T[] arr = new T[100]; // Define the indexer, which will allow client code // to use [] notation on the class instance itself. // (See line 2 of code in Main below.) public T this[int i] { get { // This indexer is very simple, and just returns or sets // the corresponding element from the internal array. return arr[i]; } set { arr[i] = value; } } } // This class shows how client code uses the indexer. class Program { static void Main(string[] args) { // Declare an instance of the SampleCollection type. SampleCollection<string> stringCollection = new SampleCollection<string>(); // Use [] notation on the type. stringCollection[0] = "Hello, World"; System.Console.WriteLine(stringCollection[0]); } }
接口中的索引器:
interface (C# Reference)." data-guid="9d8d9a82ccf82d740176b0fc9dbd9f72">索引器可在接口上声明。 class indexers in the following ways:" data-guid="6f6aa5a1638e327697f0ddb85ba767e0">接口索引器的访问器与类索引器的访问器具有以下方面的不同:
接口访问器不使用修饰符。
接口访问器没有体。
因此,访问器的用途是指示索引器是读写、只读还是只写。
以下是接口索引器访问器的示例:
public interface ISomeInterface
{
//...
// Indexer declaration:
string this[int index]
{
get;
set;
}
}
一个索引器的签名必须区别于在同一接口中声明的其他所有索引器的签名。
下面的示例显示如何实现接口索引器。
// 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();
}
}
/* Sample output:
Element #0 = 360877544
Element #1 = 327058047
Element #2 = 1913480832
Element #3 = 1519039937
Element #4 = 601472233
Element #5 = 323352310
Element #6 = 1422639981
Element #7 = 1797892494
Element #8 = 875761049
Element #9 = 393083859
*/
在上例中,可以通过使用接口成员的完全限定名来使用显式接口成员实现。 例如:
public string ISomeInterface.this { }
但是,只有当类使用同一索引器签名实现一个以上的接口时,为避免多义性才需要使用完全限定名。 Employee class is implementing two interfaces, ICitizen and IEmployee, and both interfaces have the same indexer signature, the explicit interface member implementation is necessary." data-guid="e374dc17743742840037ade58d9182f1">例如,如果 Employee 类实现的是两个接口 ICitizen 和 IEmployee,并且这两个接口具有相同的索引器签名,则必须使用显式接口成员实现。 即,以下索引器声明:
public string IEmployee.this { }
在 IEmployee 接口上实现索引器,而以下声明:
public string ICitizen.this { }
在 ICitizen 接口上实现索引器。