• 重学c#系列——索引器(九)


    前言

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

    正文

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

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

    系列持续更新中。

  • 相关阅读:
    python+requests+excel 接口测试
    Pycharm配置git
    ubuntu16.04+ROS安装kinectV1
    ubuntu16.04安装有道词典
    ROS kinetic语音识别
    在Ubuntu16.04中python环境下实现tab键补全
    ros kinetic安装rbx1
    ubuntu14.04安装opencv3.1
    ubuntu16.04SSH无法连接
    VC6中函数点go to definition报告the symbol XXX is undefined
  • 原文地址:https://www.cnblogs.com/aoximin/p/13896139.html
Copyright © 2020-2023  润新知