且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

认识索引器

更新时间:2022-10-04 14:34:16

索引器的基础就不多说了,主要就是用对象加下标来获取对象内的私有序列数据。
下面看这样一个类:
    class MyClass
    {
        string[] StrArr = new string[] { "a", "b", "c" };
        public string this[int i]
        {
            get
            {
                return StrArr[i];
            }
            set
            {
                StrArr[i] = value;
            }
        }
可以看到,索引器本来是没有名字的,因为在这里是用一个this来代替。
做个反射,我们来看看索引器转成什么了。
static void Main(string[] args)
        {
            foreach (var v in typeof(MyClass).GetMembers())
            {
                Console.WriteLine(v.Name);
            }
}
运行结果是:
get_Item
set_Item
ToString
Equals
GetHashCode
GetType
.ctor
Item
属性是由两个访问器方法构成,索引器同样也是,但有所不同的是,索引的这两个访问器方法增加了两个参数,并且方法名是固定的,如下:
public void set_Item(intstring value) i,
{
    this.StrArr[i] = value;
}
public string get_Item(int i)
{
    return this.StrArr[i];
}
这个固定的名称就是Item了,可以证名一下,可以在MyClass类中添加如下代码:
        int item;
        public int Item
        {
            get
            {
                return Item;
            }
            set
            {
                Item = value;
            }
 }
上面的代码加入后会报错,错误如下:
类型“ConsoleApplication7.MyClass”已经包含“Item”的定义。这就验证了索引器是一个Item了。
还有,索引器是可以重载的,在原来的MyClass中代码如下:
        Hashtable ht = new Hashtable();
        public MyClass()
        {
            ht.Add("1", "aaaaa");
            ht.Add("2", "bbbbb");
            ht.Add("3", "ccccc");
        }
        public object this[string i]
        {
            get
            {
                return ht[i];
            }
            set
            {
                ht[i] = value;
            }
 }
其实这个很好理解,也就是说这个实现了两个索引器get和set方法的重载。
如果一个索引器利用反射来调用,实现如下:
        ConstructorInfo ci = typeof(MyClass).GetConstructor(new Type[0]);
        MyClass mc = (MyClass)ci.Invoke(new Object[0]);
 Console.WriteLine(typeof(MyClass).GetProperty("Item").GetValue(mc, new object[] { 1 }));
如果在一个类中,有两个索引器,这种情况就会报错,虽然在GetValue的第二个参数object[]中是整型的1,系统还是分不清,所以只能换用另一种方法了,如下:
            ConstructorInfo ci = typeof(MyClass).GetConstructor(new Type[0]);
            MyClass mc = (MyClass)ci.Invoke(new Object[0]);
            Console.WriteLine(typeof(MyClass).GetProperties()[0].GetValue(mc, new object[] { 1 }));
     Console.WriteLine(typeof(MyClass).GetProperties()[1].GetValue(mc, new object[] { "1" }));




















本文转自桂素伟51CTO博客,原文链接: http://blog.51cto.com/axzxs/384906,如需转载请自行联系原作者