索引器-Indexer(MSDN)

索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同的是它们的访问器采用参数。

(为类或结构的实例建立索引)
索引器使您得以按照与数组相同的方式为类或结构实例建立索引。若要声明索引器,请使用以下方式:

[attributes] [modifiers] indexer-declarator {accessor-declarations}

indexer-declarator 采用下列形式之一:

type this [formal-index-parameter-list]
type interface-type.this [formal-index-parameter-list]

formal-index-parameter 采用的形式为:

[attributes] type identifier

其中:

attributes(可选)
附加的声明性信息。有关属性和属性类的更多信息,请参见 C# 属性
modifiers(可选)
可以使用的修饰符为 newvirtualsealedoverrideabstractextern 以及四个访问修饰符的有效组合。有关详细信息,请参见 访问修饰符
indexer-declarator
包括由索引器引入的元素 type(即 this)以及 formal-index-parameter-list。如果索引器为显式接口成员实现,则包括 interface-type
type
类型名称。
interface-type
接口名称。
formal-index-parameter-list
指定索引器的参数。参数包括可选的 attributes、索引 type 和索引 identifier。必须至少指定一个参数。不允许参数修饰符 outref
accessor-declarations
索引器访问器,它们指定与读写索引器元素有关的可执行语句。
identifier
参数名。
get 访问器

索引器的 get 访问器体与方法体类似。它返回索引器的类型。get 访问器使用与索引器相同的 formal-index-parameter-list。例如:

get 
{
   return myArray[index];
}
set 访问器

索引器的 set 访问器体与方法体类似。除了 value 隐式参数外,它还使用与索引器相同的 formal-index-parameter-list。例如:

set 
{
   myArray[index] = value;
}
备注

索引器的类型和 formal-index-parameter-list 中引用的每个类型必须至少与索引器本身一样是可访问的。有关可访问级别的更多信息,请参见访问修饰符

索引器的签名由其形参的数量和类型组成。它不包括索引器类型或形参名。

如果在同一类中声明一个以上的索引器,则它们必须具有不同的签名。

索引器值不作为变量来分类;因此,不可能将索引器值作为 refout 参数来传递。

若要为索引器提供可由其他语言用于默认索引属性的名称,可在声明中使用 name 属性。例如:

[System.Runtime.CompilerServices.CSharp.IndexerName("MyItem")]
public int this [int index]   // Indexer declaration
{
}

此索引器将具有名称 MyItem。如果不提供 name 属性,则默认名称为 Item

示例

以下示例说明如何声明私有数组字段、myArray 和索引器。通过使用索引器可直接访问实例 b[i]。另一种使用索引器的方法是将数组声明为 public 成员并直接访问它的成员 myArray[i]

// cs_keyword_indexers.cs
using System;
class IndexerClass 
{
   private int [] myArray = new int[100]; 
   public int this [int index]   // Indexer declaration
   {
      get 
      {
         // Check the index limits.
         if (index < 0 || index >= 100)
            return 0;
         else
            return myArray[index];
      }
      set 
      {
         if (!(index < 0 || index >= 100))
            myArray[index] = value;
      }
   }
}

public class MainClass 
{
   public static void Main() 
   {
      IndexerClass b = new IndexerClass();
      // Call the indexer to initialize the elements #3 and #5.
      b[3] = 256;
      b[5] = 1024;
      for (int i=0; i<=10; i++) 
      {
         Console.WriteLine("Element #{0} = {1}", i, b[i]);
      }
   }
}
输出
Element #0 = 0
Element #1 = 0
Element #2 = 0
Element #3 = 256
Element #4 = 0
Element #5 = 1024
Element #6 = 0
Element #7 = 0
Element #8 = 0
Element #9 = 0
Element #10 = 0

注意,当计算索引器的访问时(例如,在 Console.Write 语句中),调用 get 访问器。因此,如果 get 访问器不存在,将发生编译时错误。

当索引器声明包含 extern 修饰符时,称该索引器为外部索引器。因为外部索引器声明不提供任何实际的实现,所以它的每个访问器声明都由一个分号组成。

下面的示例声明了一个 BitArray 类,该类实现了一个索引器,用于访问位数组中的单个位。

using System;
class BitArray
{
   int[] bits;
   int length;
   public BitArray(int length) {
      if (length < 0) throw new ArgumentException();
      bits = new int[((length - 1) >> 5) + 1];
      this.length = length;
   }
   public int Length {
      get { return length; }
   }
   public bool this[int index] {
      get {
         if (index < 0 || index >= length) {
            throw new IndexOutOfRangeException();
         }
         return (bits[index >> 5] & 1 << index) != 0;
      }
      set {
         if (index < 0 || index >= length) {
            throw new IndexOutOfRangeException();
         }
         if (value) {
            bits[index >> 5] |= 1 << index;
         }
         else {
            bits[index >> 5] &= ~(1 << index);
         }
      }
   }
}

BitArray 类的实例所占的内存远少于相应的 bool[](这是由于前者的每个值只占一位,而后者的每个值要占一个字节),而且,它可以执行与 bool[] 相同的操作。

下面的 CountPrimes 类使用 BitArray 和经典的“筛选”算法计算 1 和给定的最大数之间质数的数目:

class CountPrimes
{
   static int Count(int max) {
      BitArray flags = new BitArray(max + 1);
      int count = 1;
      for (int i = 2; i <= max; i++) {
         if (!flags[i]) {
            for (int j = i * 2; j <= max; j += i) flags[j] = true;
            count++;
         }
      }
      return count;
   }
   static void Main(string[] args) {
      int max = int.Parse(args[0]);
      int count = Count(max);
      Console.WriteLine("Found {0} primes between 1 and {1}", count, max);
   }
}

请注意,访问 BitArray 的元素的语法与访问 bool[] 的元素的语法完全相同。

下列示例显示一个具有带两个参数的索引器的 26 乘 10 网格类。第一个参数必须是 A–Z 范围内的大写或小写字母,而第二个参数必须是 0–9 范围内的整数。

using System;
class Grid
{
   const int NumRows = 26;
   const int NumCols = 10;
   int[,] cells = new int[NumRows, NumCols];
   public int this[char c, int col] {
      get {
         c = Char.ToUpper(c);
         if (c < 'A' || c > 'Z') {
            throw new ArgumentException();
         }
         if (col < 0 || col >= NumCols) {
            throw new IndexOutOfRangeException();
         }
         return cells[c - 'A', col];
      }
      set {
         c = Char.ToUpper(c);
         if (c < 'A' || c > 'Z') {
            throw new ArgumentException();
         }
         if (col < 0 || col >= NumCols) {
            throw new IndexOutOfRangeException();
         }
         cells[c - 'A', col] = value;
      }
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值