索引器的本质

讲索引器的本质前,先说说属性的本质,在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     }

 索引器的本质

你可能感兴趣的:(索引)