C#索引器

来源:互联网 发布:windows cortana如何 编辑:程序博客网 时间:2024/04/30 04:23

简单说来,所谓索引器就是一类特殊的属性,通过它们你就可以像引用数组一样引用自己的类。
声明方法如下(与属性相似)

//
修饰符 类型名称 this [类型名称 参数名
]
public type this [int index]
{
get
{
//...
}
set
{
//...
}
}
用例子简单说明:

using System.Collections;

static void Main(string[] args)
{
//
调用IntBits.IntBits方法,意为将63赋给
bits
IntBits bits = new IntBits(63);
//
获得索引6bool值,此时 bits[6]将调用索引器"public bool this[int index]"中的Get,值为
True
bool peek = bits[6];
Console.WriteLine("bits[6] Value: {0}",peek);
bits[0] = true;
Console.WriteLine();

Console.ReadKey();
}

struct IntBits
{
private int bits;
public IntBits(int initialBitValue)
{
bits = initialBitValue;
Console.WriteLine(bits);
}
//
定义索引器

//
索引器的属性名this,意思是回引类的当前实例,参数列表包含在方括号而非括号之内。

public bool this [int index]
{
get
{
return true;
}
set
{
if (value)
{
bits = 100;
}
}
}

备注
:

所有索引器都使用this关键词来取代方法名。ClassStruct只允许定义一个索引器,而且总是命名为this


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


get
访问器返回值。set 访问器分配值。


this
关键字用于定义索引器。


value
关键字用于定义由 set 索引器分配的值。


索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制。


索引器可被重载。


索引器可以有多个形参,例如当访问二维数组时。


索引器可以使用百数值下标,而数组只能使用整数下标:如下列定义一个String下标的索引器

public int this [string name] {...}

属性和索引器


属性和索引器之间有好些差别:


类的每一个属性都必须拥有唯一的名称,而类里定义的每一个索引器都必须拥有唯一的签名(signature)或者参数列表(这样就可以实现索引器重载)。


属性可以是static(静态的)而索引器则必须是实例成员。


为索引器定义的访问函数可以访问传递给索引器的参数,而属性访问函数则没有参数。

 

 

 

 

其目的包括:

1.了解什么是索引指示器

 

2.如何实现索引指示器

 

3.重载索引指示器

 

4.了解如何实现多参数的索引指示器

 

索引指示器并不难使用。它们的用法跟数组相同。在一个类内部,你可以按照你的意愿来管理一组数据的集合。这些对象可以是类成员的有限集合,也可以是另外一个数组,或者是一些复杂的数据结构。不考虑类的内部实现,其数据可以通过使用索引指示器来获得。如下是一个例子:

 

1.清单 11-1. 索引指示器的例子:IntIndexer.cs

 

using System;

///

/// A simple indexer example.

///

class IntIndexer

{

    private string[] myData;

 

    public IntIndexer(int size)

    {

        myData = new string[size];

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

        {

            myData[i] = "empty";

        }

    }

    public string this[int pos]

    {

        get

        {

            return myData[pos];

        }

        set

        {

            myData[pos] = value;

        }

    }

 

    static void Main(string[] args)

    {

        int size = 10;

        IntIndexer myInd = new IntIndexer(size);

        myInd[9] = "Some Value";

        myInd[3] = "Another Value";

        myInd[5] = "Any Value";

        Console.WriteLine("/nIndexer Output/n");

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

        {

            Console.WriteLine("myInd[{0}]: {1}", i, myInd[i]);

        }

        Console.ReadLine();

    }

}

 

 

 

 

说明

 

1.清单 11-1演示了如何实现一个索引指示器, IntIndexer类有个名为myData的字符串数组,该数组是私有成员,因而其外部成员是看不见的。该数组是在构造函数中进行初始化的,该构造函数带有一个整型size参数,用来初始化myData数组,初始化时 把单词"empty"作为每个数组元素的值。

 

2.IntIndexer类的下一成员是索引指示器(Indexer),由关键字this和方括号[int pos]标识出来。该成员带有一个位置参数pos。正如你已经猜测到,Indexer的实现同属性一样。Indexerget set访问操作,就同属性中的用法一样。索引指示器(indexer)返回一个字符串,在定义索引指示器时,string这个类型名标志着其返回类型为字符串类型。

 

3.Main()方法完成如下事情:初始化一个新的IntIndexer对象,添加一些值,并且打印出结果。其输出结果如下:

 

Indexer Output

 

myInd[0]: empty

myInd[1]: empty

myInd[2]: empty

myInd[3]: Another Value

myInd[4]: empty

myInd[5]: Any Value

myInd[6]: empty

myInd[7]: empty

myInd[8]: empty

myInd[9]: Some Value

 

4.在不少程序语言中,通常都是使用整数作为下标来访问作为数组元素的,但C#的索引指示器不仅能够做到这一点,而且还能够更进一步。 定义索引指示器时,可以带有多个参数,每个参数的类型可以不同。添加的参数由逗号隔开,同方法中的的参数表一样。索引指示器的合法的参数类型包括:整型,枚举类型和字符串。另外,索引指示器也可以被重载。在清单 11-2中,我们修改了前面的程序,以便用来重载索引指示器 ,从而可以接受不同类型的参数。

 

2.清单 11-2. 重载的索引指示器: OvrIndexer.cs

 

using System;

///

/// Implements overloaded indexers.

/// 索引器重载

///

class OvrIndexer

{

    private string[] myData;

    private int arrSize;

    public OvrIndexer(int size)//构造函数

    {

        arrSize = size;

        myData = new string[size];

        for (int i = 0; i < myData.Length; i++)

        {

            myData[i] = "empty";

        }

    }

    //定义用int型下标访问的索引器,DataReader[0]

    public string this[int pos]

    {

        get

        {

            return myData[pos];

        }

        set

        {

            myData[pos] = value;

        }

    }

 

    //定义利用string型下标访问索引器,DDateReader["学号"]

    public string this[string data]

    {

        get

        {

            int count = 0;

            for (int i = 0; i < myData.Length; i++)

            {

 

                if (myData[i] == data)

                    count++;  

             }

            return count.ToString();

        }

 

        set

        {

            for (int i = 0; i < myData.Length; i++)

            {

                if (myData[i] == data)

                    myData[i] = value;

            }

        }

    }

}

 

class Test

{

    static void Main()

    {

        int size = 10;

        OvrIndexer myInd = new OvrIndexer(size);

        myInd[9] = "Some Value";

        myInd[3] = "Another Value";

        myInd[5] = "Anly Value";

        myInd["empty"] = "New Empty";

 

        Console.WriteLine("/nIndexer Output/n");

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

        {

            Console.WriteLine("myInd[{0}]={1}",i,myInd[i]);

        }

 

        Console.WriteLine("/nNumber of /"New Empty/" entries: {0}", myInd["New Empty"]);

        Console.ReadLine();

    }

}

 

 

 

 

说明

 

1.清单 11-2 演示了如何重载索引指示器。

 

带有整型参数pos的第一个索引指示器同清单11-1中的一样,但是,该程序中有个带有字符串参数的新的索引指示器。对于这个新的索引指示器来说,其get操作返回的是同参数值data相匹配的成员的个数。 Set操作把数组中同参数值匹配的元素值该变为value值。

 

2.在清单11-2Main()方法中,演示了重载的索引指示器,它接受字符串参数。

 

该重载的索引指示器调用了set操作,通过使用下列命令: myInd["empty"] = " New Empty"; set操作把New Empty"值赋给myInd 类中所有的值为"empty"的成员。 myInd类的每个成员都已经输出之后,就把最后一个数据输出到控制台,该数据统计数组成员值为"New Empty"的个数。 使用如下命令:myInd["New Empty"],就可调用get操作。输出结果如下:

 

Indexer Output

myInd[0]: New Empty

myInd[1]: New Empty

myInd[2]: New Empty

myInd[3]: Another Value

myInd[4]: New Empty

myInd[5]: Any Value

myInd[6]: New Empty

myInd[7]: New Empty

myInd[8]: New Empty

myInd[9]: Some Value

 

Number of "New Empty" entries: 7

 

3.在清单 11-2中,两个索引指示器共处在同一个类中, 这是可以的,因为它们有不同的特征。

 

一个索引指示器的特征是通过索引指示器参数表中的参数个数和类型表现出来的。类能够辨别出其特征,并调用相应的索引指示器。带有多个参数的索引指示器可以用如下格式来实现:

 

public object this[int param1, ..., int paramN]

{

get

{

// process and return some class data

}

set

{

// process and assign some class data

}

}

 

小结

现在你已经了解了索引指示器是用来做什么的,以及其用法。如同数组的用法一样,你可以创建索引指示器来访问类的成员。本文也提到了索引指示器的重载和多参数索引指示器。

 

 

 

 

原创粉丝点击