课程表

C# 基础教程

C# 高级教程

C# 工具/手册

工具箱
速查手册

C# 反射(Reflection)

当前位置:免费教程 » 程序设计 » C#

反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。

您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

优缺点

优点:

  • 1、反射提高了程序的灵活性和扩展性。
  • 2、降低耦合性,提高自适应能力。
  • 3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

  • 1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
  • 2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

反射(Reflection)的用途

反射(Reflection)有下列用途:

  • 它允许在运行时查看属性(attribute)信息。
  • 它允许审查集合中的各种类型,以及实例化这些类型。
  • 它允许延迟绑定的方法和属性(property)。
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。

查看元数据

我们已经在上面的章节中提到过,使用反射(Reflection)可以查看属性(attribute)信息。

System.Reflection 类的 MemberInfo 对象需要被初始化,用于发现与类相关的属性(attribute)。为了做到这点,您可以定义目标类的一个对象,如下:

  1. System.Reflection.MemberInfo info = typeof(MyClass);

下面的程序演示了这点:

  1. using System;
  2.  
  3. [AttributeUsage(AttributeTargets.All)]
  4. public class HelpAttribute : System.Attribute
  5. {
  6. public readonly string Url;
  7.  
  8. public string Topic // Topic 是一个命名(named)参数
  9. {
  10. get
  11. {
  12. return topic;
  13. }
  14. set
  15. {
  16.  
  17. topic = value;
  18. }
  19. }
  20.  
  21. public HelpAttribute(string url) // url 是一个定位(positional)参数
  22. {
  23. this.Url = url;
  24. }
  25.  
  26. private string topic;
  27. }
  28. [HelpAttribute("Information on the class MyClass")]
  29. class MyClass
  30. {
  31. }
  32.  
  33. namespace AttributeAppl
  34. {
  35. class Program
  36. {
  37. static void Main(string[] args)
  38. {
  39. System.Reflection.MemberInfo info = typeof(MyClass);
  40. object[] attributes = info.GetCustomAttributes(true);
  41. for (int i = 0; i < attributes.Length; i++)
  42. {
  43. System.Console.WriteLine(attributes[i]);
  44. }
  45. Console.ReadKey();
  46.  
  47. }
  48. }
  49. }

我来试一下

当上面的代码被编译和执行时,它会显示附加到类 MyClass 上的自定义属性:

HelpAttribute

实例

在本实例中,我们将使用在上一章中创建的 DeBugInfo 属性,并使用反射(Reflection)来读取 Rectangle 类中的元数据。

  1. using System;
  2. using System.Reflection;
  3. namespace BugFixApplication
  4. {
  5. // 一个自定义属性 BugFix 被赋给类及其成员
  6. [AttributeUsage(AttributeTargets.Class |
  7. AttributeTargets.Constructor |
  8. AttributeTargets.Field |
  9. AttributeTargets.Method |
  10. AttributeTargets.Property,
  11. AllowMultiple = true)]
  12.  
  13. public class DeBugInfo : System.Attribute
  14. {
  15. private int bugNo;
  16. private string developer;
  17. private string lastReview;
  18. public string message;
  19.  
  20. public DeBugInfo(int bg, string dev, string d)
  21. {
  22. this.bugNo = bg;
  23. this.developer = dev;
  24. this.lastReview = d;
  25. }
  26.  
  27. public int BugNo
  28. {
  29. get
  30. {
  31. return bugNo;
  32. }
  33. }
  34. public string Developer
  35. {
  36. get
  37. {
  38. return developer;
  39. }
  40. }
  41. public string LastReview
  42. {
  43. get
  44. {
  45. return lastReview;
  46. }
  47. }
  48. public string Message
  49. {
  50. get
  51. {
  52. return message;
  53. }
  54. set
  55. {
  56. message = value;
  57. }
  58. }
  59. }
  60. [DeBugInfo(45, "Zara Ali", "12/8/2012",
  61. Message = "Return type mismatch")]
  62. [DeBugInfo(49, "Nuha Ali", "10/10/2012",
  63. Message = "Unused variable")]
  64. class Rectangle
  65. {
  66. // 成员变量
  67. protected double length;
  68. protected double width;
  69. public Rectangle(double l, double w)
  70. {
  71. length = l;
  72. width = w;
  73. }
  74. [DeBugInfo(55, "Zara Ali", "19/10/2012",
  75. Message = "Return type mismatch")]
  76. public double GetArea()
  77. {
  78. return length * width;
  79. }
  80. [DeBugInfo(56, "Zara Ali", "19/10/2012")]
  81. public void Display()
  82. {
  83. Console.WriteLine("Length: {0}", length);
  84. Console.WriteLine("Width: {0}", width);
  85. Console.WriteLine("Area: {0}", GetArea());
  86. }
  87. }//end class Rectangle
  88. class ExecuteRectangle
  89. {
  90. static void Main(string[] args)
  91. {
  92. Rectangle r = new Rectangle(4.5, 7.5);
  93. r.Display();
  94. Type type = typeof(Rectangle);
  95. // 遍历 Rectangle 类的属性
  96. foreach (Object attributes in type.GetCustomAttributes(false))
  97. {
  98. DeBugInfo dbi = (DeBugInfo)attributes;
  99. if (null != dbi)
  100. {
  101. Console.WriteLine("Bug no: {0}", dbi.BugNo);
  102. Console.WriteLine("Developer: {0}", dbi.Developer);
  103. Console.WriteLine("Last Reviewed: {0}",
  104. dbi.LastReview);
  105. Console.WriteLine("Remarks: {0}", dbi.Message);
  106. }
  107. }
  108. // 遍历方法属性
  109. foreach (MethodInfo m in type.GetMethods())
  110. {
  111. foreach (Attribute a in m.GetCustomAttributes(true))
  112. {
  113. DeBugInfo dbi = (DeBugInfo)a;
  114. if (null != dbi)
  115. {
  116. Console.WriteLine("Bug no: {0}, for Method: {1}",
  117. dbi.BugNo, m.Name);
  118. Console.WriteLine("Developer: {0}", dbi.Developer);
  119. Console.WriteLine("Last Reviewed: {0}",
  120. dbi.LastReview);
  121. Console.WriteLine("Remarks: {0}", dbi.Message);
  122. }
  123. }
  124. }
  125. Console.ReadLine();
  126. }
  127. }
  128. }
  129.  

我来试一下

当上面的代码被编译和执行时,它会产生下列结果:

Length: 4.5
Width: 7.5
Area: 33.75
Bug No: 49
Developer: Nuha Ali
Last Reviewed: 10/10/2012
Remarks: Unused variable
Bug No: 45
Developer: Zara Ali
Last Reviewed: 12/8/2012
Remarks: Return type mismatch
Bug No: 55, for Method: GetArea
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks: Return type mismatch
Bug No: 56, for Method: Display
Developer: Zara Ali
Last Reviewed: 19/10/2012
Remarks: 
转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号