反射指程序可以访问、检测和修改它本身状态或行为的一种能力。
程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
优点:
缺点:
反射(Reflection)有下列用途:
我们已经在上面的章节中提到过,使用反射(Reflection)可以查看属性(attribute)信息。
System.Reflection 类的 MemberInfo 对象需要被初始化,用于发现与类相关的属性(attribute)。为了做到这点,您可以定义目标类的一个对象,如下:
System.Reflection.MemberInfo info = typeof(MyClass); |
using System; |
[AttributeUsage(AttributeTargets.All)] |
public class HelpAttribute : System.Attribute |
{ |
public readonly string Url; |
public string Topic // Topic 是一个命名(named)参数 |
{ |
get |
{ |
return topic; |
} |
set |
{ |
topic = value; |
} |
} |
public HelpAttribute(string url) // url 是一个定位(positional)参数 |
{ |
this.Url = url; |
} |
private string topic; |
} |
[HelpAttribute("Information on the class MyClass")] |
class MyClass |
{ |
} |
namespace AttributeAppl |
{ |
class Program |
{ |
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)来读取 Rectangle 类中的元数据。
using System; |
using System.Reflection; |
namespace BugFixApplication |
{ |
// 一个自定义属性 BugFix 被赋给类及其成员 |
[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 = "Return type mismatch")] |
[DeBugInfo(49, "Nuha Ali", "10/10/2012", |
Message = "Unused variable")] |
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 = "Return type mismatch")] |
public double GetArea() |
{ |
return length * width; |
} |
[DeBugInfo(56, "Zara Ali", "19/10/2012")] |
public void Display() |
{ |
Console.WriteLine("Length: {0}", length); |
Console.WriteLine("Width: {0}", width); |
Console.WriteLine("Area: {0}", GetArea()); |
} |
}//end class Rectangle |
class ExecuteRectangle |
{ |
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 no: {0}", dbi.BugNo); |
Console.WriteLine("Developer: {0}", dbi.Developer); |
Console.WriteLine("Last Reviewed: {0}", |
dbi.LastReview); |
Console.WriteLine("Remarks: {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 no: {0}, for Method: {1}", |
dbi.BugNo, m.Name); |
Console.WriteLine("Developer: {0}", dbi.Developer); |
Console.WriteLine("Last Reviewed: {0}", |
dbi.LastReview); |
Console.WriteLine("Remarks: {0}", dbi.Message); |
} |
} |
} |
Console.ReadLine(); |
} |
} |
} |
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: |