在开发过程中对于反射的知识总是印象不深刻,今天写个简单的例子帮助自己巩固
创建一个类库,类库中添加一个窗体,在窗体中添加一系列字段、属性、私有函数、公开函数、构造函数等,编译生成dll。
另外打开一个窗体的应用程序,引用之前的dll,利用反射获得程序集,实现通过反射取到dll中的函数方法,并且打开dll中存在的窗体。
命名空间:System.Reflection
System.Type
System.Reflection.Assembly
//获取程序集(第一种) Assembly assembly = Assembly.Load("ClassSum"); //获得程序集(第二种) Assembly assembly2 = Assembly.LoadFrom("ClassSum.dll"); //从程序集中获取指定对象的类型 Type type = assembly.GetType("ClassSum.CustomerForm"); if (type != null) { this.thistype = type; } this.thisclass = this.thistype.GetConstructor(new Type[] { }).Invoke(new object[] { });
得到程序集有两种方法,根据类库名称或者根据编译得到的dll文件名,这里我把得到的程序集和对象类型通过全局成员变量保存在内存中方便接下来的操作。
thistype为dll中窗体的对象类型
thisclass为实例
窗体实际上是一个特殊的类,它和其他类一样有构造函数,本文中的窗体构造函数如下
/// <summary> /// 窗体无参构造函数 /// </summary> public CustomerForm() { InitializeComponent(); } /// <summary> /// 窗体有参构造函数 /// </summary> /// <param name="formName"></param> /// <param name="isVisible"></param> public CustomerForm(string formName, bool isVisible) { this.FormName = formName; this.IsVisible = isVisible; InitializeComponent(); }
dll中的窗体构造函数分为一类是无参的,另外一个是有参数的构造函数,为了体现效果fromName为Form的Text值,isVisible为窗体的按钮是否显示。
2.1 无参打开
/// <summary> /// 无参打开 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { //1.使用Activator创建无参构造实例 var form = Activator.CreateInstance(this.thistype); //2.使用反射创建无参构造实例 ConstructorInfo constructorInfo = this.thistype.GetConstructor(new Type[] { }); var form2 = constructorInfo.Invoke(new object[] { }); //3.使用Assembly创建无参构造实例 Assembly assembly = Assembly.Load("ClassSum"); var form3 = assembly.CreateInstance("ClassSum.CustomerForm"); //可以将form1 form2 form3转化为窗体并且打开 Form getform = (Form)form2; getform.ShowDialog(); }
2.2 有参打开
/// <summary> /// 有参打开 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_Click(object sender, EventArgs e) { //获得构造函数的值 string formName = this.txtId.Text.Trim(); bool isShow = this.checkBox1.Checked; //1.使用Activator创建有参实例 var form1 = Activator.CreateInstance(this.thistype,formName,isShow); //2.使用反射创建有参实例 ConstructorInfo constructor =this.thistype.GetConstructor(new Type[] { typeof(string),typeof(bool)}); var form2 = constructor.Invoke(new object[] { formName,isShow }); Form getForm = (Form)form1; getForm.ShowDialog(); }
2.3 演示效果
dll中的方法为
/// <summary> /// 公有Public无参无返回 /// </summary> /// <returns></returns> public void PublicShowNoReturn() { MessageBox.Show("Public无参无返回"); } /// <summary> /// 私有Private无参无返回 /// </summary> /// <returns></returns> private void PrivateNoReturn() { MessageBox.Show("Private无参无返回"); } /// <summary> /// 带参带返回值 /// </summary> /// <param name="name"></param> /// <returns></returns> public string ReturnString(string name) { return "返回值是:" + name; } /// <summary> /// 静态函数返回值 /// </summary> /// <returns></returns> public static string StaticMethod() { return "静态函数的返回值"; }
3.1 Public无参数无返回值
/// <summary> /// public无参无返回 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { //调用public函数(无参数) thistype.InvokeMember("PublicShowNoReturn", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null,thisclass, null); }
3.2 Private无参数无返回值
/// <summary> /// 私有无参无返回 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button4_Click(object sender, EventArgs e) { // 调用私有方法 . thistype.InvokeMember("PrivateNoReturn", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, thisclass, new object[] { }); }
3.3 Public有参有返回值
/// <summary> /// public有参有返回 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button5_Click(object sender, EventArgs e) { string returnValue = this.thistype.InvokeMember("ReturnString", BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, thisclass, new object[] { "CallmeYhz" }) as string; MessageBox.Show(returnValue); }
3.4 Static方法
/// <summary> /// 调用静态方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button10_Click(object sender, EventArgs e) { // 调用静态方法 string returnValue2 = this.thistype.InvokeMember("StaticMethod", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { }) as string; MessageBox.Show(returnValue2); }
注:thistype为保存在内存中的类型,thisclass为保存在内存中的实例,上文有说明。
3.5 演示效果
dll中的字段和属性
/// <summary> /// 窗体字段 /// </summary> public string field = "我是字段"; private int num = 100; /// <summary> /// 窗体属性 /// </summary> public int Attribute { get { return num; } set { num = value; } }
4.1 设置属性和获取属性
//设置属性(设置Attribute属性为200) this.thistype.InvokeMember("Attribute", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null, thisclass, new object[] { 200 }); //反射属性获取打印出 var getAttribute = Convert.ToInt32( this.thistype.InvokeMember("Attribute", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, thisclass, new object[] { })); MessageBox.Show("得到的属性为:" + getAttribute);
4.2设置字段和获取字段
//设置字段(设置field字段为"我是新字段") this.thistype.InvokeMember("field", BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance, null, thisclass, new object[] { "我是新字段" }); //反射字段打印出 string field = this.thistype.InvokeMember("field", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance, null, this.thisclass, new object[] { }) as string; MessageBox.Show("得到的字段为:" + field);
4.3 演示效果
以上的内容很基础,也很重要,虽然花了些时间,但是我认为值得的,一份简单的笔记也是成长道路必不可少的里程碑。。。
原文:http://www.cnblogs.com/CallmeYhz/p/5010650.html