索引器的本质

讲索引器的本质前,先说说属性的本质,在IL里面我们可以清楚地看到,属性的get和set两个访问器,其实就是直接调用类里面定义的两个方法: set_属性名|get_属性名.

所以访问属性的途径,除了反射获取Propertie以外,我们可以绕过属性对象,直接调用set_属性名|get_属性名方法。

索引器除了具备属性的特性之外,索引器所对应的属性名必须为Item,如果一个类中定义了索引器,又定义了一个名为Item的属性,结果就会提示同名的错误.

除此之外,从IL中看出,属性本身就是特殊的方法,一般的属性都不带参数,而索引器至少带一个参数.如图:

 1 public  class getset
 2     {
 3         int[,] ary=new int[3,3] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
 4 
 5         int _num;
 6         public int Num
 7         {
 8             get
 9             {
10                 return _num;
11             }
12             set
13             {
14                 _num=value;
15             }
16         }
17         public int this[int arg1]
18         {
19             get
20             {
21                 return ary[arg1%3, arg1%3];
22             }
23             set
24             {
25                 ary[arg1%3, arg1%3]=value;
26             }
27         }
28         public int this[int arg1, int arg2]
29         {
30             get
31             {
32                 return ary[arg1%3,arg2%3];
33             }
34             set
35             {
36                 ary[arg1%3, arg2%3]=value;
37             }
38         }
39         //索引器是特殊的属性 其属性名是Item
40         //定义Item属性无法通过编译
41         //public int Item
42         //{
43         //    get;
44         //    set;
45         //}
46         public void Show()
47         {
48             for(int i=0;i<3;i++)
49             {
50                 Console.WriteLine(ary[i, 0]+"\t"+ary[i, 1]+"\t"+ary[i, 2]);
51             }
52         }
53 
54         public static void Test()
55         {
56 
57             getset item=new getset();
58             var type=typeof(getset);
59             var arg=new object[] { 2,2};
60 
61             foreach (var p in type.GetProperties().Where(o => o.Name=="Item"))
62             {
63                 Console.Write("Parameter Length:"+p.GetIndexParameters().Length+"\r\n\t   ReturenType:"+p.PropertyType+"   Parameters Type:");
64                 foreach (var a in p.GetIndexParameters())
65                 {
66                     Console.Write(a.ParameterType+"\t");
67                 }
68                 Console.WriteLine();
69             }
70 
71             var method = type.GetMethod("get_Item",new Type[]{typeof(int),typeof(int)});
72             Console.WriteLine(method.Invoke(item, arg));
73  
74 
75            var prop = type.GetProperty("Item",typeof(int),new Type[]{typeof(int),typeof(int)});
76 
77 
78             
79 
80            Console.WriteLine(prop.GetIndexParameters().Length);
81 
82            prop.GetValue(item, arg);             
83            
84            prop.GetSetMethod().Invoke(item, new object[] { 123, 456,999});
85            Console.WriteLine(prop.GetGetMethod().Invoke(item, new object[] { 2, 1 }));
86 
87 
88            item.Show();
89           
90         }
91     }

 

原文地址:https://www.cnblogs.com/AspDotNetMVC/p/2932169.html