索引器允許類或結構的實例就像數組一樣進行索引。索引器類似於屬性,不同之處在於它們的訪問器采用參數。
在下面的示例中,定義了一個泛型類,並為其提供了簡單的 get 和 set 訪問器方法(作為分配和檢索值的方法)。Program 類為存儲字符串創建了此類的一個實例。
class SampleCollection<T>
{
private T[] arr = new T[100];
public T this[int i]
{
get
{
return arr[i];
}
set
{
arr[i] = value;
}
}
}
// This class shows how client code uses the indexer
class Program
{
static void Main(string[] args)
{
SampleCollection<string> stringCollection = new SampleCollection<string>();
stringCollection[0] = "Hello, World";
System.Console.WriteLine(stringCollection[0]);
}
}
this,類的索引器:
下面的示例說明如何聲明私有數組字段、temps 和索引器。使用索引器可直接訪問實例 tempRecord[i]。另一種使用索引器的方法是將數組聲明為 public 成員並直接訪問它的成員 tempRecord.temps[i]。
請注意,當計算索引器的訪問時(例如,在 Console.Write 語句中),將調用 get 訪問器。因此,如果 get 訪問器不存在,將發生編譯時錯誤。
代碼
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();
}
}
說明
在此例中,聲明了存儲星期幾的類。聲明了一個 get 訪問器,它接受字符串(天名稱),並返回相應的整數。例如,星期日將返回 0,星期一將返回 1,等等。
代碼
// Using a string as an indexer value
class DayCollection
{
string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };
// This method finds the day or returns -1
private int GetDay(string testDay)
{
for(int j = 0; j < days.Length - 1; j++)
{
if (days[j] == testDay)
{
return j;
}
}
throw new System.ArgumentOutOfRangeException(testDay, "testDay must be in the form \"Sun\", \"Mon\", etc");
}
// The get accessor returns an integer for a given string
public int this[string day]
{
get
{
return (GetDay(day));
}
}
}
class Program
{
static void Main(string[] args)
{
DayCollection week = new DayCollection();
System.Console.WriteLine(week["Fri"]);
// Raises ArgumentOutOfRangeException
System.Console.WriteLine(week["Made-up Day"]);
// Keep the console window open in debug mode.
System.Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
}
}
// Output: 5
提高索引器的安全性和可靠性有兩種主要的方法:
-
確保結合某一類型的錯誤處理策略,以處理萬一客戶端代碼傳入無效索引值的情況。在本主題前面的第一個示例中,TempRecord 類提供了 Length 屬性,使客戶端代碼能夠在將輸入傳遞給索引器之前對其進行驗證。也可以將錯誤處理代碼放入索引器自身內部。確保為用戶記錄在索引器的訪問器中引發的任何異常。有關更多信息,請參見異常設計准則。
-
應當為 get 和 set 訪問器的可訪問性設置盡可能多的限制。這一點對 set 訪問器尤為重要。有關更多信息,請參見 非對稱訪問器可訪問性(C# 編程指南)。
屬性和索引器之間的比較:
索引器與屬性類似。除下表中顯示的差別外,為屬性訪問器定義的所有規則同樣適用於索引器訪問器。
屬性 |
索引器 |
---|---|
允許像調用公共數據成員一樣調用方法。 |
允許對一個對象本身使用數組表示法來訪問該對象內部集合中的元素。 |
可通過簡單的名稱進行訪問。 |
可通過索引器進行訪問。 |
可以為靜態成員或實例成員。 |
必須為實例成員。 |
屬性的 get 訪問器沒有參數。 |
索引器的 get 訪問器具有與索引器相同的形參表。 |
屬性的 set 訪問器包含隱式 value 參數。 |
除了值參數外,索引器的 set 訪問器還具有與索引器相同的形參表。 |
支持對自動實現的屬性(C# 編程指南)使用短語法。 |
不支持短語法。 |