索引器:是C#引入的一個(gè)新型的類(lèi)成員,它允許類(lèi)或結(jié)構(gòu)的實(shí)例按照與數(shù)組相同的方式進(jìn)行索引。
索引器類(lèi)型于屬性,它們的不同之處在于索引器的訪問(wèn)器采用參數(shù)。
定義了索引器之后,就可以像訪問(wèn)數(shù)組一樣,使用[]運(yùn)算符訪問(wèn)類(lèi)的成員。
定義索引器的方式與定義屬性有些類(lèi)似,其一般形式如下:
[修飾符] 數(shù)據(jù)類(lèi)型 this <[數(shù)據(jù)類(lèi)型 標(biāo)識(shí)符]>
{
get{//獲得屬性的代碼}
set{//設(shè)置屬性的代碼}
}
索引器概述:
使用索引器可以用類(lèi)似于數(shù)組的方式為對(duì)象建立索引。
get accessor returns a value." data-guid="5e97def07fe15e931d526cafa5b97644">get 訪問(wèn)器返回值。 set accessor assigns a value." data-guid="66b9797a805b510e697d60c805140aeb">set 訪問(wèn)器分配值。
this keyword is used to define the indexers." data-guid="c34f23e68daf270013978542591de397">this 關(guān)鍵字用于定義索引器。
value keyword is used to define the value being assigned by the set indexer." data-guid="599578d2a780928307c04f6ca2b0f058">value 關(guān)鍵字用于定義由 set 索引器分配的值。
索引器不必根據(jù)整數(shù)值進(jìn)行索引,由您決定如何定義特定的查找機(jī)制。
索引器可被重載。
索引器可以有多個(gè)形參,例如當(dāng)訪問(wèn)二維數(shù)組時(shí)。
屬性與索引器的比較:
屬性 | 索引器 |
允許像調(diào)用公共數(shù)據(jù)成員一樣調(diào)用方法 | 允許對(duì)一個(gè)對(duì)象本身使用數(shù)組表示法來(lái)訪問(wèn)該對(duì)象內(nèi)部集合中的元素 |
可通過(guò)簡(jiǎn)單的名稱(chēng)進(jìn)行訪問(wèn) | 可通過(guò)索引器進(jìn)行訪問(wèn) |
可以為靜態(tài)成員或?qū)嵗蓡T | 必須為實(shí)例成員 |
get accessor of a property has no parameters." data-guid="a6cc8a328d7d6f37fe6726bef0a1e49b">屬性的 get 訪問(wèn)器沒(méi)有參數(shù) | get accessor of an indexer has the same formal parameter list as the indexer." data-guid="d83df23e86b78dbdb4847d31d82a2337">索引器的 get 訪問(wèn)器具有與索引器相同的形參表 |
set accessor of a property contains the implicit value parameter." data-guid="7b8d943b10ea3a65d99f8a3c0b284e05">屬性的 set 訪問(wèn)器包含隱式 value 參數(shù) | set accessor of an indexer has the same formal parameter list as the indexer, and also to the value parameter." data-guid="61fa719a7490fc5fb284c6b5ef3c3c36">除了值參數(shù)外,索引器的 set 訪問(wèn)器還具有與索引器相同的形參表 |
Auto-Implemented Properties (C# Programming Guide)." data-guid="0980783e25d81c644f0194104a5b78f1">支持對(duì)自動(dòng)實(shí)現(xiàn)的屬性(C# 編程指南)使用短語(yǔ)法 | 不支持短語(yǔ)法 |
get and set accessor methods as a means of assigning and retrieving values." data-guid="dd23dc3354d63d8f7d007da64625c804"> 在下面的示例中,定義了一個(gè)泛型類(lèi),并為其提供了簡(jiǎn)單的 get 和 set 訪問(wèn)器方法(作為分配和檢索值的方法)。 Program class creates an instance of this class for storing strings." data-guid="6ddaa503e5fad577a85f10e9f502a5c1">Program 類(lèi)為存儲(chǔ)字符串創(chuàng)建了此類(lèi)的一個(gè)實(shí)例。
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">接口索引器的訪問(wèn)器與類(lèi)索引器的訪問(wèn)器具有以下方面的不同:
接口訪問(wèn)器不使用修飾符。
接口訪問(wèn)器沒(méi)有體。
因此,訪問(wèn)器的用途是指示索引器是讀寫(xiě)、只讀還是只寫(xiě)。
以下是接口索引器訪問(wèn)器的示例:
public interface ISomeInterface
{
//...
// Indexer declaration:
string this[int index]
{
get;
set;
}
}
一個(gè)索引器的簽名必須區(qū)別于在同一接口中聲明的其他所有索引器的簽名。
下面的示例顯示如何實(shí)現(xiàn)接口索引器。
// 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
*/
在上例中,可以通過(guò)使用接口成員的完全限定名來(lái)使用顯式接口成員實(shí)現(xiàn)。 例如:
public string ISomeInterface.this { }
但是,只有當(dāng)類(lèi)使用同一索引器簽名實(shí)現(xiàn)一個(gè)以上的接口時(shí),為避免多義性才需要使用完全限定名。 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 類(lèi)實(shí)現(xiàn)的是兩個(gè)接口 ICitizen 和 IEmployee,并且這兩個(gè)接口具有相同的索引器簽名,則必須使用顯式接口成員實(shí)現(xiàn)。 即,以下索引器聲明:
public string IEmployee.this { }
在 IEmployee 接口上實(shí)現(xiàn)索引器,而以下聲明:
public string ICitizen.this { }
在 ICitizen 接口上實(shí)現(xiàn)索引器。