前言

对于索引器,我们肯定不会陌生。为什么会有索引器这个东西呢?我们发现这东西很像是属性,只是通过索引方式去调用,那就慢慢揭开他的面纱吧。

正文

假设我们要对外暴露一个数组,为了体现其封装性,我们使用数组。

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;
}

系列持续更新中。