C#中的索引器(Indexers)


 

前兩天剛剛學習完了屬性,這兩天又摟完了索引器,發現兩者非常的相似,但是相似之外還有一些不同之處。今天就來總結一下索引器--Indexers

索引器的作用及格式

索引器的作用就是能夠使類或者結構體的實例對象像數組一樣使用下標的方式訪問集合對象。索引器的書寫格式和屬性非常的類似,像是一個帶有參數的屬性,但是屬性名只能使用this關鍵字,並且指定了索引類型,下面看一個簡單的例子:

  class MyClass{
     int[] numInts = new int[10];//定義一個數組
     public int this[int index]{
         get
        {
             return numInts[index];
        }
         set
        {
             numInts[index] = value;
        }
    }
}
 
 class Program
{
static void Main(string[] args)
{
MyClass myClass = new myClass();
myClass[0] = 1;
myClass[1] = 2;
int num = myClass[1];
}
}

在這個例子中,myClass通過get訪問器獲取numInts中的值,通過set訪問器將值傳遞給value進行賦值,這是最簡單的操作。但其實在get和set訪問器中還可以進行一些條件的判斷,比如在get訪問器中判斷下標是否越界;在set訪問器中判斷傳值是否超出限定范圍等等,能做的操作太多了。

只讀&只寫索引器的實現

上面說過,索引器與屬性非常的相似都具有一對訪問器,只是訪問器接收的參數有所不同。既然擁有類似的訪問器,那么只讀或者只寫功能的索引器與只讀或者只寫功能的屬性,也是差不多的,下面具體闡述一下。 在之前的屬性文章的說到過屬性的只讀或者只寫有兩種實現方式:

  1. 隱藏getter或者setter

  2. 給getter或者setter添加private訪問修飾符 這里同樣適用於索引器,只不過有以下幾點需要注意:

  3. 通過隱藏getter來實現只讀索引器的方式,只能在類中實現,結構體中的索引器不能隱藏getter

  4. 通過給getter添加private訪問修飾符實現只讀索引器也只能在類中實現,結構體中getter必須能被外界訪問到

  5. 使用添加private訪問修飾符的方式來是實現只讀或者只寫索引器時,getter和setter必須同時存在,缺一不可。 下面使用兩種方式分別實現只讀索引器:

class MyClass
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index]//通過添加private實現只寫索引器
{
get{
               return this.nums[index];
}
private set { this.nums[index] = value; }
}
}

class MyClass
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index]//通過隱藏setter實現只讀索引器
{
get{
               return this.nums[index];
}
}
}

索引器在接口中的使用

接口中能夠聲明的類型只有四種,其中就包含索引器。在接口中,索引器的使用也和屬性大抵相似,getter和setter同樣沒有方法體,只用";"結尾。也可以通過隱藏getter或者setter來定義只讀或者只寫索引器,具體在接口中的使用如下:

  interface ITestFace
{
int this[int index] { get; set; }
}

同屬性一樣,派生類在實現索引器的時候也有兩種選擇:

  1. 可以為索引器添加virtual關鍵字,使后續的派生類能夠進行重寫

class Test2:ITestFace
{
private int[] count = new[] {1, 2, 3, 4};
public virtual int this[int index]
{
get => count[index];
set => count[index] = value;
}
}

class Test1:Test2
{
private int[] count = new[] {0,0,0,0 };
public override int this[int index]
{
get
{
return this.count[index];
}
}
}
class Program
{
static void Main(string[] args)
{
Test2 Test1 = new Test1();
Console.WriteLine(Test1[1]);
}
}
0
請按任意鍵繼續. . .
  1. 直接在索引器前添加接口名稱,刪除訪問修飾符,進行顯示接口實現

class Test2:ITestFace
{
private int[] count = new[] {1, 2, 3, 4};
int ITestFace.this[int index]
{
get => count[index];
set => count[index] = value;
}
}
class Program
{
static void Main(string[] args)
{
ITestFace tf = new Test2();
Console.WriteLine(tf[1]);
}
}
2
請按任意鍵繼續. . .

使用顯示接口實現的形式,索引器不屬於派生類所有,只能被對應接口類型的派生類實例對象所使用。

索引器的其他使用方式

以上用到的索引器都是只包含一個索引值,但其實索引器的所引致可以包含多個,根據自己的需求來使用,這里就不過多介紹了,需要的可以自行Google或者百度。下面介紹一下如何在索引器中使用表達式主體定義。 表達式主體定義和lambda表達式很像,概念什么的這里就略去了,直接進入主題,在C#6當中,如果索引器只讀,且get訪問器只有一條語句,那么就可以使用表達式主體定義的方式進行書寫,更加簡潔:

  
 class MyClass2
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index] => this.nums[index];
}

這種方式只適用於只讀索引器,但是在C#7當中,還有另外一種使用表達式主體定義的方式,來簡便的書寫索引器,如下所示:

  class MyClass3
{
private int[] nums = new []{1, 2, 3, 4, 5, 6, 7};

public int this[int index] {
           get=>this.nums[index];
           set=> nums[index] = value;
}
}

以上,就是關於索引器的一些內容,不足之處還請指教,下面列出一些使用索引器的注意事項,供大家使用時參考:

  1. 通過索引器傳遞進來的值會傳遞給value變量,value的類型必須與索引器的類型相同

  2. 索引器不能作為ref或者out參數使用,數組可以

  3. 索引器只屬於對象,不能使用static進行修飾

  4. 結構體中也可以使用屬性,但是使用時結構體需要使用關鍵字new進行初始化,因為索引器只屬於對象

  5. 索引器和屬性很相似,屬於有參的屬性,使類或者結構體可以訪問像數組一下訪問數據

  6. 使用索引器獲取數據或者修改數據,接收或者傳遞的值的類型必須與索引器的類型相同

  7. 索引器和屬性相同,也可以通過隱藏get或者set訪問器來實現只讀索引器或者只寫索引器,但是在結構體中必須保留get訪問器,類中可以選擇性的隱藏

  8. 索引器的只讀或者只寫也可以通過給get或者set訪問器添加合適的訪問修飾符private來實現,但是在結構體中get訪問器不能設為私有的或者被保護的,只能為public類型的

PS:以上均是自己學習之后理解所寫,水平有限難免會出現錯誤之處,總是唯恐給閱讀到小伙伴造成誤導,所以希望能夠以質疑的態度去瀏覽,也希望小伙伴能夠批評指出,共同成長。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM