C#反射
反射(Reflection)对象有用于在运行时获取类型信息。
这个类位于System.Reflection命名空间中,可以访问一个正在运行的程序的元数据。
反射(Reflection)的用途如下:
1.可以在运行时查看属性(Attribute)信息
2.可以审查集合中的各种类型,以及实例化这些类型
3.可以延迟绑定的方法和属性
4.可以运行时创建新类型,然后使用这些类型执行一些任务
- 查看元数据
System.Reflection类的MemberInfo对象被初始化,用于发现与类相关的属性。
可以如下一样定义一个目标类的对象:
System.Reflection.MemberInfo info = typeof(MyClass);
使用Visual Studio 新建C#控制台应用程序chapter22_001
定义一个属性以及属性应用的类:
[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
{
}
在Main方法中新增如下代码进行测试:
System.Reflection.MemberInfo info = typeof(MyClass);
object[] attributes = info.GetCustomAttributes(true);
for (int i = 0; i < attributes.Length; i++)
{
Console.WriteLine(attributes[i]);
}
Console.ReadKey();
编译运行的结果如下:
在C#每日一课(二十六)中有说到新增了DeBugInfo类
使用Visual Studio 新建C#控制台应用程序chapter22_002
声明一个DeBugInfo类,并使用自定义特性
//一个自定义的类属性赋给类及其成员
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : Attribute
{
private int bugNo;
private string developer;
private string lastReview;
private 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;
}
}
}
新增一个Student类
//为Class定义属性
[DeBugInfo(12,"xiesheng","12/12/2017",Message ="DeBug Student 20171212")]
[DeBugInfo(13, "advent", "13/12/2017", Message = "DeBug Student 20171213")]
class Student
{
protected string name;
protected string school;
public Student(string n, string s)
{
this.name = n;
this.school = s;
}
//为Method定义属性
[DeBugInfo(14, "advent", "14/12/2017", Message = "DeBug Student.ToDo() 20171214")]
public string ToDo()
{
return "我是学生我在学习!";
}
[DeBugInfo(15, "advent", "15/12/2017", Message = "DeBug Student.Display() 20171215")]
public void Display()
{
Console.WriteLine("名字:{0}", this.name);
Console.WriteLine("学校:{0}", this.school);
}
}
在Main方法中加入如下代码进行测试:
Student stu = new Student("谢声","西安交通大学");
stu.Display();
//类类型
Type type = typeof(Student);
//遍历Student类属性
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 (Object a in m.GetCustomAttributes(true))
{
/*
* as是用来类型转换的,例如两个类:A和B ;B b = new B();
* 不用as,进行强制转换,如果类型不匹配,会引发转换异常A a = (A) b;
* 使用as,类型不匹配,不会引发异常,会返回一个null,此时 a = null ;A a = b as A;
*/
// DeBugInfo dbi = (DeBugInfo)a;这句会报转换错误,改为下面
DeBugInfo dbi = a as DeBugInfo;
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.ReadKey();
编译运行结果如下: