代码改变世界

C#拾遗系列(4):索引器

2008-06-11 15:30  敏捷的水  阅读(562)  评论(0编辑  收藏  举报

1. 概述

索引器允许类或结构的实例就像数组一样进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。索引器在语法上方便您创建客户端应用程序可将其作为数组访问的类、结构或接口。索引器经常是在主要用于封装内部集合或数组的类型中实现的。

例如,假定具有一个名为 TempRecord 的类,此类表示在 24 小时内的 10 个不同时间记录的华氏度。此类包含一个表示温度的 float 类型的名为“temps”的数组和表示记录温度的日期的 DateTime。通过在此类中实现一个索引器,客户端可以通过 float temp = tr[4] 而不是 float temp = tr.temps[4] 语法访问 TempRecord 实例中的温度。索引器表示法不仅简化了客户端应用程序的语法,还使其他开发人员能够更加直观地理解类及其用途。使用索引器可以用类似于数组的方式为对象建立索引。

get 访问器返回值。set 访问器分配值。this 关键字用于定义索引器。value 关键字用于定义由 set 索引器分配的值。

索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。索引器可被重载索引器可以有多个形参,例如当访问二维数组时。

2. 示例:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace NetTest

{    

    public class TestIndexClass

    {

        public void Test()

        {

            TempRecord tempRecord = new TempRecord();

            // Use the indexer's set accessor

            tempRecord[3] = 58.3F;

            tempRecord[5] = 60.1F;

 

            // Use the indexer's get accessor

            for (int i = 0; i < 10; i++)

            {

                // This example validates the input on the client side. You may

                // choose to validate it in the class that implements the indexer, and throw an

                // exception or return an error code in the case of invalid input.

                if (i < tempRecord.Length)

                {

                    System.Console.WriteLine("Element #{0} = {1}", i, tempRecord[i]);

                }

                else

                {

                    System.Console.WriteLine("Index value of {0} is out of range", i);

                }

            }

 

            //Uncomment this code to see how the .NET Framework handles indexer exceptions

            //try

            //{

            //    System.Console.WriteLine("Element #{0} = {1}", tempRecord[tempRecord.Length]);

            //}

            //catch (System.ArgumentOutOfRangeException e)

            //{

            //    System.Console.WriteLine(e);

            //}

 

            DayCollection week = new DayCollection();

            System.Console.WriteLine(week["Fri"]);

            System.Console.WriteLine(week["Made-up Day"]);

 

        }

    }

 

 

    class TempRecord

    {

        // Array of temperature values

        private float[] temps = new float[10] { 56.2F, 56.7F, 56.5F, 56.9F, 58.8F,

                                            61.3F, 65.9F, 62.1F, 59.2F, 57.5F };

        // Auto-Implemented Property

        System.DateTime date { get; set; }

        // To enable client code to validate input

        // when accessing your indexer.

        public int Length

        {

            get { return temps.Length; }

        }

        // Indexer declaration.

        // Input parameter is validated by client

        // code before being passed to the indexer.

        public float this[int index]

        {

            get

            {

                return temps[index];

            }

 

            set

            {

                temps[index] = value;

            }

        }

    }

 

 

 

    //C# 并不将索引类型限制为整数。例如,对索引器使用字符串可能是有用的。通过搜索集合内的字符串并返回相应的值,可以实现此类索引器。

    //由于访问器可被重载,字符串和整数版本可以共存。

 

    class DayCollection

    {

        string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };

 

        // This method finds the day or returns -1

        private int GetDay(string testDay)

        {

            int i = 0;

            foreach (string day in days)

            {

                if (day == testDay)

                {

                    return i;

                }

                i++;

            }

            return -1;

        }

 

        // The get accessor returns an integer for a given string

        public int this[string day]

        {

            get

            {

                return (GetDay(day));

            }

        }

    }

 

 

}