深刻理解反射(Reflection)

最近公司在搞自动化测试,由于版权问题,无法用 ’录制脚本‘ 进行,也就没法用 VS 自带的 UITest 框架(蛋疼), 所以只能开源的 FlaUI 框架来搞了。其中不可避免的涉及到反射的应用,但自己有些概念还是有点模糊不清, 干脆集中将自己个人的理解整理一下。

一、前提

要理解反射首先要理解 特性 的概念,因为反射通常需要获取用户自定义属性。

特性(Attribute)

概念: 用于在运行时传递程序中各种元素(类,方法等)的行为信息的声明性标签。

声明方法:在它所应用的元素(类, 方法等)面前防止方框号([ ]), ig. [SayHelloAttribute]。

主要作用:对应用的元素添加元数据, 程序可以使用反射检查获取自己的元数据或者其它元素内的元数据。

可以这么理解元数据的概念:程序集中所有关于声明类的数据信息(成员函数, 属性, 方法调用)等都储存在元数据里面(pdb 文件)。

如果还不理解特性的概念, 点这里 https://en.wikipedia.org/wiki/Attribute_(computing)

二、 概念

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

作用: 通过反射, 可以在运行时获取指定程序集(dll 集合) 每一个类型(包括类、结构、委托、接口等)的成员(方法、事件、属性等)。

三、用途

反射可以作用在程序集上, 程序集包含模块, 模块包含类型,类型又包含成员, 反射可以对封装程序集、模块、类以及成员进行操作。通常,使用反射动态的创建类型的实例, 将类型绑定到现有对象(或从现有对象获取类型), 然后调用类型的方法。

最常见用途如下:

 1、使用 Assembly 定义和加载程序集, 并提取指定的类型集合。

如下所示, 加载 "ReflectionTest.exe"  , 提取程序中有 “HelloAttribute" 属性的类。

1 Assembly a = Assembly.Load("ReflectionTest.exe");
2 // 当 dll 与 类唯一时, 以下两种获取 type 方式等效 
3 // 与下面方式等效 Type assType = typeof(HelloWorld);
4 Type[] assTypes = a.GetTypes();
5 foreach (Type assType in assTypes)
6 {
7      object[] attributes = assType.GetCustomAttributes(typeof(HelloAttribute), false);
8 }

2、使用 MethodInfo 了解方法的名称, 返回类型,参数 以及实现信息。

 // HellowWord 是一个类
1
Type = Typeof(HelloWord) 2 var m = t.GetMethods(); 3 foreach (MethodInfo mInfo in m) 4 { 5 // 此处考虑了 attributeMutiple = true 的情况 6 foreach (Attribute aa in mInfo.GetCustomAttributes(true)) 7 { 8 HelloAttribute d = aa as HelloAttribute; 9 if (null != d) 10 { 11 Console.WriteLine("the method is you wanted: {0}", m); 12 } 13 } 14 }

3、实例化对象, 调用方法

1 Type t = typeof(HelloWorld);
2 // 实例化 HelloWorld
3 Object obj = Activator.CreateInstance(t);
4 
5 // 调用 Hello 方法(’Hello‘ 方法在 ’HelloWorld‘ 类中已经实现过)
6 MethodInfo custHello = t.GetMethod("Hello")
7 custHello.Invoke(parame) // parame 指的是对应的参数。

本次用到的方法主要是以上三种,这次也先写这么多,后期用到其它方法,再来更新。

原文地址:https://www.cnblogs.com/yaolin1228/p/7667572.html