C#-反射机制的简单示例

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

通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。

例如有一个学生类Student,包含有字段,属性及方法

 1     class Student
 2     {
 3         public Student(string name, int age, bool isboy)
 4         {
 5             this.name = name;
 6             this.age = age;
 7             this.isBoy = isboy;
 8         }
 9         public string name;
10         public int grade = 3;
11         public int age;
12         public bool isBoy { get; set; }
13         public void Learn1(string work) { Console.WriteLine("I'm Working1 Now:" + work); }
14         public void Learn2(string work) { Console.WriteLine("I'm Working2 Now:" + work); }
15         public void Learn3(string work) { Console.WriteLine("I'm Working3 Now:" + work); }
16     }
Student

下面使用反射来对其进行各种操作,首先引入命名空间:

using System.Reflection;

使用反射实例化一个对象:

//Student stu = new Student("Frankie", 10, true);
Student stu = (Student)Activator.CreateInstance(typeof(Student), new[] { "Frankie", (object)10, (object)true });

使用反射获取Student类中都有哪些成员:

 1         static void GetAll(object sender)
 2         {
 3             Console.WriteLine("/*******获取对象中所有字段属性方法及值********/");
 4             Type t = sender.GetType();
 5             PropertyInfo[] pros = t.GetProperties();
 6             FieldInfo[] fies = t.GetFields();
 7             MethodInfo[] meths = t.GetMethods();
 8             foreach (var v in pros)
 9                 Console.WriteLine("属性:" + v.Name + ":" + v.GetValue(sender));
10             foreach (var v in fies)
11                 Console.WriteLine("字段:" + v.Name + ":" + v.GetValue(sender));
12             foreach (var v in meths)
13                 Console.WriteLine("方法:" + v.Name);
14         }
GetAll()

使用反射对stu对象中的字段和属性进行修改,并执行它的方法

 1         static void Modify(object sender)
 2         {
 3             Console.WriteLine("/*******修改对象的所有字段属性值并调用方法********/");
 4             Type t = sender.GetType();
 5             PropertyInfo p = t.GetProperty("isBoy");
 6             p.SetValue(sender, false);
 7             FieldInfo f = t.GetField("name");
 8             f.SetValue(sender, "jeny");
 9             f = t.GetField("grade");
10             f.SetValue(sender, 8);
11             f = t.GetField("age");
12             f.SetValue(sender, 15);
13             for (int i = 1; i < 4; i++)
14             {
15                 MethodInfo m = t.GetMethod("Learn" + i);
16                 m.Invoke(sender, new[] { i.ToString() });
17             }
18         }
Modify()

查看构造函数和它的参数名称及类型:

1             ConstructorInfo[] infos = t.GetConstructors();
2             foreach (var v in infos)
3             {
4                 ParameterInfo[] paras = v.GetParameters();
5                 foreach (var p in paras)
6                 {
7                     Console.WriteLine(p.Name + ":" + p.ParameterType);
8                 }
9             }    
获取构造器

使用构造器实例一个对象:

object stu = infos[0].Invoke(new object[]{});//infos[0]是ConstructorInfo

查看成员或类型是否拥有指定特性及特性的值,以实现筛选:

1    if (m.IsDefined(typeof(TestAttribute), true))
2    {
3        object[] cur = m.GetCustomAttributes(typeof(TestAttribute), false);
4        bool flag = (cur[0] as TestAttribute).flag1;
5        flag = (cur[0] as TestAttribute).flag2;
6        Console.WriteLine(m.Name);
7    }  //m可以是字段,属性,函数,构造器,类型。

反射DLL:

1       Assembly ass = Assembly.LoadFrom("ClassLibrary1.dll");
3        object obj = ass.CreateInstance("ClassLibrary1.Sheep");
4        MethodInfo m = obj.GetType().GetMethod("Voice");
5        m.Invoke(obj,null);

反射可以对每一个未知对象了如指掌且可以对其进行修改和方法调用。很有用!很强大!

 

  

posted @ 2023-01-08 18:34  [春风十里]  阅读(272)  评论(0编辑  收藏  举报