重學c#系列——索引器(九)
阿新 • • 發佈:2020-10-29
前言
對於索引器,我們肯定不會陌生。為什麼會有索引器這個東西呢?我們發現這東西很像是屬性,只是通過索引方式去呼叫,那就慢慢揭開他的面紗吧。
正文
假設我們要對外暴露一個數組,為了體現其封裝性,我們使用陣列。
public Class Instance{
public int[] IntArr{get;set;}
}
這樣似乎就可以了,但是有個問題,那就是假如我要取得是其中的一個值。
那麼可以這樣寫instance.IntArr[0],這樣寫似乎沒得啥子問題呢,但是執行過程是instance.IntArr 會建立一個匿名物件,然後再取其中的索引0。
這樣似乎是不必要的。
然後索引器可以這樣:
public Class Instance{ private int[] intArr; public int this[int index] { get { return intArr[index]; } set { intArr[i]=value; } } }
那麼呼叫方式是這樣的:instance[i]。
這種方式比較簡單,很多情況下都是不希望知道內部怎麼實現的,比如說索引是一個string,傳遞的值需要經過某種計算然後得出。
比如說官網給出一個例子:
using System; // Using a string as an indexer value class DayCollection { string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" }; // Indexer with only a get accessor with the expression-bodied definition: public int this[string day] => FindDayIndex(day); private int FindDayIndex(string day) { for (int j = 0; j < days.Length; j++) { if (days[j] == day) { return j; } } throw new ArgumentOutOfRangeException( nameof(day), $"Day {day} is not supported.\nDay input must be in the form \"Sun\", \"Mon\", etc"); } }
通過這種模式實現一個類陣列的結構,會使我們的程式碼簡潔很多。
索引還是和屬性用法還是不同的,索引只能是例項成員。我也不知道為什麼要這樣設計,但是我是這樣想得,加上其不是一個例項成員,而是一個靜態成員,似乎是沒有任何意義的,因為我沒
有找到任何這樣的意義。
值得注意的是,介面中依然存在索引。
官網給出的例子是:
// Indexer on an interface: public interface IIndexInterface { // Indexer declaration: int this[int index] { get; set; } } // Implementing the interface. class IndexerClass : IIndexInterface { private int[] arr = new int[100]; public int this[int index] // indexer declaration { // The arr object will throw IndexOutOfRange exception. get => arr[index]; set => arr[index] = value; } }
和介面定義的規則一樣,在介面中我們不能去做具體的試下,只需定義即可。
因為介面可以繼承,那麼可能會形成屬性衝突,那麼具體實現的時候就需要:
public int IIndexInterface.this[int index] // indexer declaration
{
// The arr object will throw IndexOutOfRange exception.
get => arr[index];
set => arr[index] = value;
}
結
系列持續更新中。