面试官经常问到的反射到底是什么?
终于在项目中遇到了
背景:
前段时间,质量管理模块的同事,询问在质量链中打开我销售模块的销售订单,要调用我销售订单管理类中打开的具体的销售订单
要用反射调用
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ReflectTest { //这就是销售订单管理类 public class SOMgrForm { public string Soid { get; set; } /// <summary> /// 打开单据 /// </summary> /// <param name="soId"></param> /// <param name="showType"></param> public string ShowOrders(string soId, string showType) { return string.Format(@"打开单据:{0}或者:{2},打开方式{1}", soId, showType,Soid); } } }
由于整个产品的dll文件会在一个目录下,那么我将上述编译的dll文件放到下面winform执行程序目录下
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Reflection;//用到的引用 using System.IO; namespace ReflectTestApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// 点击反射调用打开 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Assembly assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory+ "ReflectTest.dll");//加载反射的dll //string path = Path.Combine(Application.StartupPath, "ReflectTest.dll"); //Assembly assembly2 = Assembly.LoadFile(path); Assembly assembly3 = Assembly.Load("ReflectTest");//当前路径下 Type type = assembly.GetType("ReflectTest.SOMgrForm");//获取类型信息 object obj = type.Assembly.CreateInstance(type.FullName);//创建类型的实例 //object o = Activator.CreateInstance(type); PropertyInfo propertyInfo = null; propertyInfo = type.GetProperty("Soid");//获取该类型属性 propertyInfo.SetValue(obj,"111111",null);//赋值 MethodInfo methodInfo = type.GetMethod("ShowOrders");//获取该类型方法 string str=Convert.ToString( methodInfo.Invoke(obj,new object[] { "33","44"}));//调用方法 this.textBox1.Text = str; } } }
运行结果:
1、什么是反射
Reflection,中文翻译为反射。
这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:
Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。
Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。
MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。
诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。
2、命名空间与装配件的关系
很多人对这个概念可能还是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。
命名空间类似与Java的包,但又不完全等同,因为Java的包必须按照目录结构来放置,命名空间则不需要。
装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。
装配件和命名空间的关系不是一一对应,也不互相包含,一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在
注意是在运行时,而不是说在你敲代码时调用dll,添加引用
1.问Net应用程序执行的最小单位是什么
.dll、.exe
1、现实应用程序中很少有应用程序需要使用反射类型
2、使用反射动态绑定需要牺牲性能
3、有些元数据信息是不能通过反射获取的
4、某些反射类型是专门为那些clr 开发编译器的开发使用的,所以你要意识到不是所有的反射类型都是适合每个人的。