您的位置:首页 > 编程语言 > C#

C#教学第15讲索引器1(学习笔记)

2008-12-14 23:24 281 查看
第15讲索引器1
快乐乔巴的博客

视频讲师:陈广老师
大家好,今天我们来讲索引器(indexer)。
索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。索引器也被称为有参属性,下面我们来看看索引器跟数组和属性之间有什么不同。
我们新建一个空白文件,首先先看看类数组是怎么使用的:
using System;
class ArrClass
{ 
    //这里记录一个用户信息的类
    private readonly string name;
    //声明一个构造函数,传递它的姓名
    public ArrClass(string name)
    {
        this.name = name;
    }
    //然后声明一个属性
    public string Name
    {
        get { return name; }
    }
}
//我们来演示类数组的使用
class text
{ 
    static void Main()
    {
        //我们首先声明了一个ArrClass类的一个数组a,并把长度设置为10
        ArrClass[] a = new ArrClass[10];
        //我们新建了三个ArrClass的实例,并把它赋给ArrClass数组a
        a[0] = new ArrClass("张三");
        a[1] = new ArrClass("李四");
        a[2] = new ArrClass("王五");
        //下面把它打印出来
        Console.WriteLine("a[0]=" + a[0].Name);
        Console.WriteLine("a[1]=" + a[1].Name);
        Console.WriteLine("a[2]=" + a[2].Name);
    }
}


通过运行,我们可以得到结果,各自人名都能显示出来。

好,下面我们声明一个带索引器的类。
using System;
class ArrClass  //没有索引器的类
{ 
    private readonly string name;
    public ArrClass(string name)
    {
        this.name = name;
    }
    public string Name
    {
        get { return name; }
    }
}
class IndexClass    //带索引器的类
{ 
    //在索引器里面声明一个字符串数组name
    private string[] name = new string[10];
    //要定义一个索引器需要使用this关键字,然后加上中括号,在其中表明索引值的类型
    //索引值是一个整型,返回值是string
    //记住:索引器永远被称为this,且它没有自己的名称,访问时需要通过它们归属的对象才行
    public string this[int index]
    { 
        //接下来需要给索引器定义get访问器和set访问器
        get { return name[index]; }
        set { name[index] = value; }
    }
}
class text
{ 
    static void Main()
    {
        //索引类的使用
        ArrClass[] a = new ArrClass[10];
        a[0] = new ArrClass("张三");
        a[1] = new ArrClass("李四");
        a[2] = new ArrClass("王五");
        Console.WriteLine("a[0]=" + a[0].Name);
        Console.WriteLine("a[1]=" + a[1].Name);
        Console.WriteLine("a[2]=" + a[2].Name);
        //索引器的使用
        IndexClass b = new IndexClass();
        //给索引器赋值跟数组赋值是一样的
        b[0] = "张三";
        b[1] = "李四";
        b[2] = "王五";
        Console.WriteLine("b[0]=" + b[0]);
        Console.WriteLine("b[1]=" + b[1]);
        Console.WriteLine("b[2]=" + b[2]);
    }
}


我们运行代码,效果如下:



我们看,a[0]a[1]a[2]是类数组,b[0]b[1]b[2]是索引器,它们得到的结果是一样的。我们来看索引器和类数组有什么区别。类数组存放的是一个一个类的实例,当然类数组的实质呢它只是存取托管堆中的内存指针,而这些内存指针就指向托管堆中的一个一个类。而索引器呢,它的这些名字(张三李四王五)其实是存放在索引器里的一个数组里面,这样呢索引器只需要声明一个实例,而类数组需要声明多个实例,当然i这个索引器并没有写完全。在get和set访问器中应该判断index的取值范围(0~9)。
这里我们也看到索引器呢提供了一i种数组封装到类的一种方法,就好象在类里面封装string或者int类型的对象一样。为了数据的安全,也可以把数据封装到类里,索引器有一个比类数组更为灵活的地方,就是它的索引值并不一定必须为整数,也就是说索引器的索引值可以为其他的数据类型,好下面我们来试验一下:
首先介绍下Hashtable,在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key和value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应key值。Hashtable中key/value键值对均为object类型,所以Hashtable可以支持任何类型的key/value键值对
ing System;
//Hashtable存在于此空间内
using System.Collections;
//我们可以把索引值的类型设置为string
class IndexClass
{
    //这里要用到一个C#自带的类型Hashtable,这里声明一个Hashtable
    private Hashtable name = new Hashtable();
    public string this[string index]
    { 
        //由于Hashtable返回的是一个object类型,所以需要把它转换为string
        get { return name[index].ToString(); }
        //给Hashtable里面加数据是通过Add函数来完成的
        //第一个参数是它的key,第二个是它的值,键和值配成一对
        //index就是下面A001编号,value就是所赋的值(张三李四王五)
        set { name.Add(index,value); }
    }
}
class text
{ 
    static void Main()
    {
        IndexClass b = new IndexClass();
        //给每个人一个编号
        b["A001"] = "张三";
        b["A002"] = "李四";
        b["A003"] = "王五";
        //我们可以通过键来访问相应的值
        Console.WriteLine("b[A001]=" + b["A001"]);
        Console.WriteLine("b[A002]=" + b["A002"]);
        Console.WriteLine("b[A003]=" + b["A003"]);
    }
}


运行代码后能正常的显示。
索引器还有一个更为吸引人的地方,就是它能够被重载。我们现在再对程序做些修改:
using System;
using System.Collections;
class IndexClass
{
    private Hashtable name = new Hashtable();
    //string修改为int
    public string this[int index]       //A索引器
    { 
        get { return name[index].ToString(); }
        set { name.Add(index,value); }
    }
    //我们重载一个this索引器,希望通过姓名来访问它的编号
    public int this[string aName]       //B索引器
    {
        //这时候我们需要遍历这个Hashtable,然后根据名字找到对应的编号,也就是说通过值来找键
        get
        {
            //Hashtable里面存放了实际上是DictonaryEntry这种类型,所以我们要遍历一个Hashtable就必须要用到DictonaryEntry
            foreach (DictionaryEntry d in name)
            {
                if (d.Value.ToString() == aName)
                { 
                    //如果找到他的名字就返回他的键值
                    return Convert.ToInt32(d.Key);
                }
            }
            return -1;
        }
        set { name.Add(value, aName); }
    }
}
class text
{ 
    static void Main()
    {
        IndexClass b = new IndexClass();
        //调用A索引器
        b[100] = "张三";
        b[200] = "李四";
        b[300] = "王五";
        Console.WriteLine("编号为100的员工是:" + b[100]);
        Console.WriteLine("编号为200的员工是:" + b[200]);
        Console.WriteLine("编号为300的员工是:" + b[300]);
        //通过名字查找编号,通过重载实现
        //调用B索引器
        Console.WriteLine("张三的编号是:" + b["张三"]);
        Console.WriteLine("李四的编号是:" + b["李四"]);
        Console.WriteLine("王五的编号是:" + b["王五"]);
        b["马六"] = 400;
        b["钱七"] = 500;
        //调用A索引器
        Console.WriteLine("编号为400的员工是:" + b[400]);
        Console.WriteLine("编号为500的员工是:" + b[500]);
    }
}


运行代码编译之后,效果如下:



我们看,运行成功。我们通过字符索引来给索引器赋值,跟前面的这个用数字索引给索引器赋值有所不同,这个是重载。实际项目上并不符合逻辑,这里只是为了给大家做一个演示。
好,这节课就演示到这里。
由快乐乔巴听课摘写笔记
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: