索引指示器
分类:多线程

本节课将介绍C#的索引指示器,其目的包括:
1.了解什么是索引指示器

索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的。

索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写。

2.如何实现索引指示器

索引器和数组比较:

1、索引器的定义

3.重载索引指示器

(1)索引器的索引值(Index)类型不受限制

C#中的类成员可以是任意类型,包括数组和集合。当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作。

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

(2)索引器允许重载

定义索引器的方式与定义属性有些类似,其一般形式如下:

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

(3)索引器不是一个变量

[修饰符] 数据类型 this[索引类型 index]

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

索引器和属性的不同点

{

using System;
///
/// A simple indexer example.
///
class IntIndexer
{
private string[] myData;

(1)属性以名称来标识,索引器以函数形式标识

get{//获得属性的代码}                                                 

set{ //设置属性的代码}

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

(2)索引器可以被重载,属性不可以

}

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 Outputn",',',');
for (int i=0; i < size; i++)
{
Console.WriteLine("myInd[{0}]: {1}", i, myInd[i],',',');
}
}
}

(3)索引器不能声明为static,属性可以

修饰符包括 public,protected,private,internal,new,virtual,sealed,override, abstract,extern.

说明

 

数据类型是表示将要存取的数组或集合元素的类型。

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

一个简单的索引器例子

索引器类型表示该索引器使用哪一类型的索引来存取数组或集合元素,可以是整数,可以是字符串;this表示操作本对象的数组或集合成员,可以简单把它理解成索引器的名字,因此索引器不能具有用户定义的名称。 例如:

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

using System;
using System.Collections;

class Z
{
//可容纳100个整数的整数集
private long[] arr = new long[100];
//声明索引器
public long this[int index]
{
get
{ //检查索引范围
if (index < 0 || index >= 100)
{
return 0;
}
else
{
return arr[index];
}
}
set
{
if (!(index < 0 || index >= 100))
{
arr[index] = value;
}
}
}

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

public class IndexerClass
{
    private string[] name = new string[2];

2、索引器的使用

Indexer Output

    //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
    public string this[int index]
    {
        //实现索引器的get方法
        get
        {
            if (index < 2)
            {
                return name[index];
            }
            return null;
        }

通过索引器可以存取类的实例的数组成员,操作方法和数组相似,一般形式如下:

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

        //实现索引器的set方法
        set
        {
            if (index < 2)
            {
                name[index] = value;
            }
        }
    }
}
public class Test
{
    static void Main()
    {
        //索引器的使用
        IndexerClass Indexer = new IndexerClass();
        //“=”号右边对索引器赋值,其实就是调用其set方法
        Indexer[0] = "张三";
       Indexer[1] = "李四";
        //输出索引器的值,其实就是调用其get方法
        Console.WriteLine(Indexer[0]);
       Console.WriteLine(Indexer[1]);
    }
}

对象名[索引]

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

 

其中索引的数据类型必须与索引器的索引类型相同。例如:

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

 

Z z=new z();

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 < size; i++)
{
myData[i] = "empty";
}
}

以字符串作为下标,对索引器进行存取

z[0]=100;

public string this[int pos]
{
get
{
return myData[pos];
}
set
{
myData[pos] = value;
}
}

public class IndexerClass
{
    //用string作为索引器下标的时候,要用Hashtable
    private Hashtable name = new Hashtable();

z[1]=101;

public string this[string data]
{
get
{
int count = 0;
for (int i=0; i < arrSize; i++)
{
if (myData[i] == data)
{
count++;
}
}
return count.ToString(,',',');
}
set
{
for (int i=0; i < arrSize; i++)
{
if (myData[i] == data)
{
myData[i] = value;
}
}
}
}

    //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
    public string this[string index]
    {
        get { return name[index].ToString();
        set { name.Add(index, value); }
    }
}
public class Test
{
    static void Main()
    {
        IndexerClass Indexer = new IndexerClass();
        Indexer["A0001"] = "张三";
        Indexer["A0002"] = "李四";
        Console.WriteLine(Indexer["A0001"]);
        Console.WriteLine(Indexer["A0002"]);
    }
}

Console.WriteLine(z[0]);

static void Main(string[] args)
{
int size = 10;
OvrIndexer myInd = new OvrIndexer(size,',',');
myInd[9] = "Some Value";
myInd[3] = "Another Value";
myInd[5] = "Any Value";
myInd["empty"] = "no value";
Console.WriteLine("nIndexer Outputn",',',');
for (int i=0; i < size; i++)
{
Console.WriteLine("myInd[{0}]: {1}", i, myInd[i],',',');
}
Console.WriteLine("nNumber of "no value" entries: {0}", myInd["no value"],',',');
}
}

 

表示先创建一个对象z,再通过索引来引用该对象中的数组元素。

说明

 索引器的重载

3、接口中的索引器

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

public class IndexerClass
{
    private Hashtable name = new Hashtable();

在接口中也可以声明索引器,接口索引器与类索引器的区别有两个:一是接口索引器不使用修饰符;二是接口索引器只包含访问器get或set,没有实现语句。访问器的用途是指示索引器是可读写、只读还是只写的,如果是可读写的,访问器get或set均不能省略;如果只读的,省略set访问器;如果是只写的,省略get访问器。

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

    //1:通过key存取Values
    public string this[int index]
    {
        get { return name[index].ToString(); }
        set { name.Add(index, value); }
    }

例如:

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

    //2:通过Values存取key
    public int this[string aName]
    {
        get
        {
            //Hashtable中实际存放的是DictionaryEntry(字典)类型,如果要遍历一个Hashtable,就需要使用到DictionaryEntry
            foreach(DictionaryEntry d in name)
            {
                if (d.Value.ToString() == aName)
                {
                    return Convert.ToInt32(d.Key);
                }
            }
            return -1;
        }
        set
        {
            name.Add(value, aName);
        }
    }
}
public class Test
{
    static void Main()
    {
        IndexerClass Indexer = new IndexerClass();

public interface IAddress

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

        //第一种索引器的使用
        Indexer[1] = "张三";//set访问器的使用
        Indexer[2] = "李四";
       Console.WriteLine("编号为1的名字:" + Indexer[1]);//get访问器的使用
        Console.WriteLine("编号为2的名字:" + Indexer[2]);

{

Indexer Output
myInd[0]: no value
myInd[1]: no value
myInd[2]: no value
myInd[3]: Another Value
myInd[4]: no value
myInd[5]: Any Value
myInd[6]: no value
myInd[7]: no value
myInd[8]: no value
myInd[9]: Some Value

        Console.WriteLine();
        //第二种索引器的使用
        Console.WriteLine("张三的编号是:" + Indexer["张三"]);//get访问器的使用
        Console.WriteLine("李四的编号是:" + Indexer["李四"]);
       Indexer["王五"] = 3;//set访问器的使用
        Console.WriteLine("王五的编号是:" + Indexer["王五"]);
    }
}

string this[int index]{get;set;}

Number of "no value" entries: 7

 

string Address{get;set;}

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

 

string Answer();

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

多参索引器

}

public object this[int param1, ..., int paramN]
{
get
{
// process and return some class data
}
set
{
// process and assign some class data
}
}

using System;
using System.Collections;

表示所声明的接口IAddress包含3个成员:一个索引器、一个属性和一个方法,其中,索引器是可读写的。

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

//入职信息类
public class EntrantInfo
{
    //姓名、编号、部门
    private string name;
    private int number;
    private string department;
    public EntrantInfo()
    {

4、索引器与属性的比较

    }
    public EntrantInfo(string name, int num, string department)
    {
        this.name = name;
        this.number = num;
        this.department = department;
    }

索引器与属性都是类的成员,语法上非常相似。索引器一般用在自定义的集合类中,通过使用索引器来操作集合对象就如同使用数组一样简单;而属性可用于任何自定义类,它增强了类的字段成员的灵活性。
图片 1

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的。

    public int Num
    {
        get { return number; }
        set { number = value; }
    }

索引器和数组比较:

    public string Department
    {
        get { return department; }
        set { department = value; }
    }
}

(1)索引器的索引值(Index)类型不受限制

//声明一个类EntrantInfo的索引器
public class IndexerForEntrantInfo
{
    private ArrayList ArrLst;//用于存放EntrantInfo类
    public IndexerForEntrantInfo()
    {
        ArrLst = new ArrayList();
    }

(2)索引器允许重载

    //声明一个索引器:以名字和编号查找存取部门信息
    public string this[string name, int num]
    {
        get
        {
            foreach (EntrantInfo en in ArrLst)
            {
                if (en.Name == name && en.Num == num)
                {
                    return en.Department;
                }
            }
            return null;
        }
        set
        {
            //new关键字:C#规定,实例化一个类或者调用类的构造函数时,必须使用new关键
            ArrLst.Add(new EntrantInfo(name, num, value));
        }
    }

(3)索引器不是一个变量

    //声明一个索引器:以编号查找名字和部门
    public ArrayList this[int num]
    {
        get
        {
            ArrayList temp = new ArrayList();
            foreach (EntrantInfo en in ArrLst)
            {
                if (en.Num == num)
                {
                    temp.Add(en);
                }
            }
            return temp;
        }
    }

索引器和属性的不同点

    //还可以声明多个版本的索引器...
}

(1)属性以名称来标识,索引器以函数形式标识

public class Test
{
    static void Main()
    {
        IndexerForEntrantInfo Info = new IndexerForEntrantInfo();
        //this[string name, int num]的使用
        Info["张三", 101] = "人事部";
        Info["李四", 102] = "行政部";
        Console.WriteLine(Info["张三", 101]);
        Console.WriteLine(Info["李四", 102]);

(2)索引器可以被重载,属性不可以

        Console.WriteLine();

(3)索引器不能声明为static,属性可以

        //this[int num]的使用
        foreach (EntrantInfo en in Info[102])
        {
            Console.WriteLine(en.Name);
            Console.WriteLine(en.Department);
        }
    }
}

一个简单的索引器例子:

 

using System;
using System.Collections;

 

public class IndexerClass
{
private string[] name = new string[2];

文章是从这里复制过来的: http://www.cnblogs.com/ArmyShen/archive/2012/08/27/2659405.html 

//索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
public string this[int index]
{
    //实现索引器的get方法
    get
    {
        if (index < 2)
        {
            return name[index];
        }
        return null;
    }

    //实现索引器的set方法
    set
    {
        if (index < 2)
        {
            name[index] = value;
        }
    }
}

 

}
public class Test
{
static void Main()
{
//索引器的使用
IndexerClass Indexer = new IndexerClass();
//“=”号右边对索引器赋值,其实就是调用其set方法
Indexer[0] = "张三";
Indexer[1] = "李四";
//输出索引器的值,其实就是调用其get方法
Console.WriteLine(Indexer[0]);
Console.WriteLine(Indexer[1]);
}
}

以字符串作为下标,对索引器进行存取:

public class IndexerClass
{
//用string作为索引器下标的时候,要用Hashtable
private Hashtable name = new Hashtable();

//索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
public string this[string index]
{
    get { return name[index].ToString(); 
    set { name.Add(index, value); }
}

}
public class Test
{
static void Main()
{
IndexerClass Indexer = new IndexerClass();
Indexer["A0001"] = "张三";
Indexer["A0002"] = "李四";
Console.WriteLine(Indexer["A0001"]);
Console.WriteLine(Indexer["A0002"]);
}
}

索引器的重载:

public class IndexerClass
{
private Hashtable name = new Hashtable();

//1:通过key存取Values
public string this[int index]
{
    get { return name[index].ToString(); }
    set { name.Add(index, value); }
}

//2:通过Values存取key
public int this[string aName]
{
    get
    {
        //Hashtable中实际存放的是DictionaryEntry(字典)类型,如果要遍历一个Hashtable,就需要使用到DictionaryEntry
        foreach(DictionaryEntry d in name)
        {
            if (d.Value.ToString() == aName)
            {
                return Convert.ToInt32(d.Key);
            }
        }
        return -1;
    }
    set
    {
        name.Add(value, aName);
    }
}

}
public class Test
{
static void Main()
{
IndexerClass Indexer = new IndexerClass();

    //第一种索引器的使用
    Indexer[1] = "张三";//set访问器的使用
    Indexer[2] = "李四";
   Console.WriteLine("编号为1的名字:" + Indexer[1]);//get访问器的使用
    Console.WriteLine("编号为2的名字:" + Indexer[2]);

    Console.WriteLine();
    //第二种索引器的使用
    Console.WriteLine("张三的编号是:" + Indexer["张三"]);//get访问器的使用
    Console.WriteLine("李四的编号是:" + Indexer["李四"]);
   Indexer["王五"] = 3;//set访问器的使用
    Console.WriteLine("王五的编号是:" + Indexer["王五"]);
}

}

多参索引器:

using System;
using System.Collections;

//入职信息类
public class EntrantInfo
{
//姓名、编号、部门
private string name;
private int number;
private string department;
public EntrantInfo()
{

}
public EntrantInfo(string name, int num, string department)
{
    this.name = name;
    this.number = num;
    this.department = department;
}

public string Name
{
    get { return name; }
    set { name = value; }
}

public int Num
{
    get { return number; }
    set { number = value; }
}

public string Department
{
    get { return department; }
    set { department = value; }
}

}

//声明一个类EntrantInfo的索引器
public class IndexerForEntrantInfo
{
private ArrayList ArrLst;//用于存放EntrantInfo类
public IndexerForEntrantInfo()
{
ArrLst = new ArrayList();
}

//声明一个索引器:以名字和编号查找存取部门信息
public string this[string name, int num]
{
    get
    {
        foreach (EntrantInfo en in ArrLst)
        {
            if (en.Name == name && en.Num == num)
            {
                return en.Department;
            }
        }
        return null;
    }
    set
    {
        //new关键字:C#规定,实例化一个类或者调用类的构造函数时,必须使用new关键
        ArrLst.Add(new EntrantInfo(name, num, value));
    }
}

//声明一个索引器:以编号查找名字和部门
public ArrayList this[int num]
{
    get
    {
        ArrayList temp = new ArrayList();
        foreach (EntrantInfo en in ArrLst)
        {
            if (en.Num == num)
            {
                temp.Add(en);
            }
        }
        return temp;
    }
}

//还可以声明多个版本的索引器...

}

public class Test
{
static void Main()
{
IndexerForEntrantInfo Info = new IndexerForEntrantInfo();
//this[string name, int num]的使用
Info["张三", 101] = "人事部";
Info["李四", 102] = "行政部";
Console.WriteLine(Info["张三", 101]);
Console.WriteLine(Info["李四", 102]);

    Console.WriteLine();

    //this[int num]的使用
    foreach (EntrantInfo en in Info[102])
    {
        Console.WriteLine(en.Name);
        Console.WriteLine(en.Department);
    }
}

}

本文由10bet手机官网发布于多线程,转载请注明出处:索引指示器

上一篇:详细介绍,1中TAG的调用方法 下一篇:没有了
猜你喜欢
热门排行
精彩图文