反射学习笔记之动态创建对象和调用方法
2010-02-24 21:14 爱研究源码的javaer 阅读(630) 评论(0) 编辑 收藏 举报动态加载和静态引用的程序集并不是同一个Assembly了。事实上,在.Net中,同一个应用程序域并不允许同时加载两个相同的Assembly。即使加载了,也会认为是两个不同的程序集。如果要同时加载两个,则必须在不同的应用程序域中。可以通过AppDomain创建一个新的应用程序域,在其中动态加载;而原来的程序域则静态添加引用。此时将会认为是同一个程序集。
猜测是如此。我需要测试。想到我最近作的Remoting。服务器端和客户端正是两个不同的应用程序域。于是我在服务器端通过Activator.CreateInstance()动态创建对象,返回object类型。
然后再客户端静态添加该对象的引用。(我在本地机上试验,所以服务器端和客户端加载的程序集完全一样,包括路径都相同)然后再客户端通过Activator.GetObject()获得服务器端动态创建的对象,再显示进行强制转换。果然,使正确的。
转自:http://www.cnblogs.com/wayfarer/archive/2004/07/20/25968.html
使用无参数构造函数创建对象
System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
Object obj = asm.CreateInstance("ReflectorDemo.Calculator", true);//true 说明是不是大小写无关(Ignore Case)。
System.Runtime.Remoting.ObjectHandle handler = Activator.CreateInstance(null, "ReflectorDemo.Calculator");//null为当前程序集
Object obj = handler.Unwrap();
使用有参数构造函数创建对象
System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
Object[] parameters = new Object[2];
parameters[0] = 3;
parameters[1] = 5;
Object obj = asm.CreateInstance("ReflectorDemo.Calculator", true, System.Reflection.BindingFlags.Default, null, parameters, null, null);
// System.Runtime.Remoting.ObjectHandle oh = AppDomain.CurrentDomain.CreateInstance(System.Reflection.Assembly.GetExecutingAssembly().FullName, controlName);
//_currentControl = (Control)oh.Unwrap();
//System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
//Object obj = asm.CreateInstance("NavigateControl.NavigatePanel", true);
//System.Runtime.Remoting.ObjectHandle handler = Activator.CreateInstance(null, "NavigateControl.NavigatePanel");//null为当前程序集
//Object obj = handler.Unwrap();
//System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
//Object obj = asm.CreateInstance("NavigateControl.NavigatePanel",true, System.Reflection.BindingFlags.Default, null,null, null, null);
Type t = typeof(NavigateControl.NavigatePanel);
Object obj = Activator.CreateInstance(t);
System.Reflection.Assembly asm = System.Reflection.Assembly.Load("NavigateControl");
Object obj = asm.CreateInstance("NavigateControl.NavigatePanel");
1.使用InvokeMember调用方法
Type t = typeof(ReflectorDemo.Calculator);//Calculator是类
int result = (int)t.InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null, obj, null);
Console.WriteLine(String.Format("The result is {0}", result));
在InvokeMember方法中,第一个参数说明了想要调用的方法名称;第二个参数说明是调用方法(因为InvokeMember的功能非常强大,不光是可以调用方法,还可以获取/设置 属性、字段等。此枚举的详情可参看Part.2或者MSDN);第三个参数是Binder,null说明使用默认的Binder;第四个参数说明是在这个对象上(obj是Calculator类型的实例)进行调用;最后一个参数是数组类型,表示的是方法所接受的参数。
我们在看一下对于静态方法应该如何调用:
Object[] parameters2 = new Object[2];
parameters2[0] = 6;
parameters2[1] = 9;
t.InvokeMember("Add", BindingFlags.InvokeMethod, null, typeof(Calculator), parameters2);
输出:
Invoke Static Method:
[Add]: 6 plus 9 equals to 15
使用MethodInfo.Invoke调用方法
//Type t = typeof(ReflectorDemo.Calculator);
//System.Reflection.MethodInfo mi = t.GetMethod("Add", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
//int result = (int)mi.Invoke(obj, null);
使用MethodInfo调用静态方法
Type t = typeof(ReflectorDemo.Calculator);
Object[] parameters2 = new Object[2];
parameters2[0] = 6;
parameters2[1] = 9;
System.Reflection.MethodInfo mi = t.GetMethod("Add", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
//int result = (int)mi.Invoke(null, parameters2);
// int result = (int)mi.Invoke(t, parameters2); //也可以这样