• 反射学习笔记之动态创建对象和调用方法


    动态加载和静态引用的程序集并不是同一个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); //也可以这样

  • 相关阅读:
    07-图4 哈利·波特的考试 (25分)
    Windows环境下清除SVN文件
    查看SQL SERVER 2008R2 表大小
    Oauth支持的5类 grant_type 及说明
    SignalR的性能监测
    Loadrunner11安装
    Azure ServiceBus 通信失败问题
    sql server text类型 存储问题
    System.BadImageFormatException
    InputStream只能读取一次的解决办法 C# byte[] 和Stream转换
  • 原文地址:https://www.cnblogs.com/johnwonder/p/1672961.html
Copyright © 2020-2023  润新知