C#反射(Reflection)
反射(Reflection)是指程序可以访问、检测和修改它本身状态或行为的一种能力,反射中提供了用来描述程序集、模块和类型的对象,可以使用反射动态地创建类型的实例,并将类型绑定到现有对象,或者从现有对象中获取类型,然后调用其方法或访问其字段和属性。 如果代码中使用了特性,也可以利用反射来访问它们。
反射的用途
C# 中反射具有以下用途:- 在运行时查看视图属性信息;
- 检查装配中的各种类型并实例化这些类型;
- 在后期绑定到方法和属性;
- 在运行时创建新类型,然后使用这些类型执行一些任务。
查看元数据
前面我们提到了可以使用反射查看特性的信息,下面就来看一下具体的操作步骤。首先需要初始化 System.Reflection 类的 MemberInfo 对象,用来发现与类关联的属性,例如:System.Reflection.MemberInfo info = typeof(MyClass);
完整的示例代码如下所示:
using System;
[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute {
public readonly string Url;
public string Topic // Topic 是一个 name_parameter
{
get {
return topic;
}
set {
topic = value;
}
}
public HelpAttribute(string url) // url 是一个 positional_parameters
{
this.Url = url;
}
private string topic;
}
[HelpAttribute("关于 MyClass 的信息")]
class MyClass {
}
namespace c.biancheng.net
{
class Demo
{
static void Main(string[] args)
{
System.Reflection.MemberInfo info = typeof(MyClass);
object[] attributes = info.GetCustomAttributes(true);
for (int i = 0; i < attributes.Length; i++) {
System.Console.WriteLine(attributes[i]);
}
Console.ReadKey();
}
}
}
运行结果如下:HelpAttribute
【示例】在本例中,我们将使用在上一节中创建的 DeBugInfo 特性,并使用反射(Reflection)来读取矩形类中的元数据。
using System;
using System.Reflection;
namespace c.biancheng.net
{
// 要分配给类及其成员的自定义属性错误修复程序
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute {
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg, string dev, string d) {
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
}
public int BugNo {
get {
return bugNo;
}
}
public string Developer {
get {
return developer;
}
}
public string LastReview {
get {
return lastReview;
}
}
public string Message {
get {
return message;
}
set {
message = value;
}
}
}
[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "返回值类型不匹配")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "变量未使用")]
class Rectangle {
// 成员变量
protected double length;
protected double width;
public Rectangle(double l, double w) {
length = l;
width = w;
}
[DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "返回值类型不匹配")]
public double GetArea() {
return length * width;
}
[DeBugInfo(56, "Zara Ali", "19/10/2012")]
public void Display() {
Console.WriteLine("长: {0}", length);
Console.WriteLine("宽: {0}", width);
Console.WriteLine("面积: {0}", GetArea());
}
}
class Demo
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(4.5, 7.5);
r.Display();
Type type = typeof(Rectangle);
// 遍历 Rectangle 类的属性
foreach (Object attributes in type.GetCustomAttributes(false)) {
DeBugInfo dbi = (DeBugInfo)attributes;
if (null != dbi) {
Console.WriteLine("Bug 编号: {0}", dbi.BugNo);
Console.WriteLine("开发者: {0}", dbi.Developer);
Console.WriteLine("上次审核时间: {0}", dbi.LastReview);
Console.WriteLine("评论: {0}", dbi.Message);
}
}
// 遍历函数属性
foreach (MethodInfo m in type.GetMethods()) {
foreach (Attribute a in m.GetCustomAttributes(true)) {
DeBugInfo dbi = (DeBugInfo)a;
if (null != dbi) {
Console.WriteLine("Bug 编号: {0}, 函数名: {1}", dbi.BugNo, m.Name);
Console.WriteLine("开发者: {0}", dbi.Developer);
Console.WriteLine("上次审核时间: {0}", dbi.LastReview);
Console.WriteLine("评论: {0}", dbi.Message);
}
}
}
Console.ReadLine();
}
}
}
运行结果如下:
长: 4.5
宽: 7.5
面积: 33.75
Bug 编号: 49
开发者: Nuha Ali
上次审核时间: 10/10/2012
评论: 变量未使用
Bug 编号: 45
开发者: Zara Ali
上次审核时间: 12/8/2012
评论: 返回值类型不匹配
Bug 编号: 55, 函数名: GetArea
开发者: Zara Ali
上次审核时间: 19/10/2012
评论: 返回值类型不匹配
Bug 编号: 56, 函数名: Display
开发者: Zara Ali
上次审核时间: 19/10/2012
评论:
ICP备案:
公安联网备案: