none
关于assembly.createinstance()返回对象不能成功完成类型转换的问题,请高手出招 RRS feed

  • 问题

  • 发现同样条件下activiator.createinstance工作而assembly.createinstance()不工作,不知道什么原因。请高手解释。
    另:Assembly load的Exe文件是后附被测代码生成的,不存在类定义不一致的问题。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Runtime.Remoting;
    using testpurpose;

    namespace _99testexe
    {
        class Programa
        {
            static void Main(string[] args)
            {
                Assembly oa = Assembly.LoadFrom(@"D:\Projects\CsharpCore\testpurpose\bin\Debug\testpurpose.exe");

                Type ot = oa.GetTypes()[0];
                object obj1 = oa.CreateInstance(ot.FullName);

                foreach (MethodInfo om in ot.GetMethods())

                    if (om.Name == "sayhi")
                        om.Invoke(obj1, null);//工作得很正常

                ObjectHandle oh = Activator.CreateInstance(oa.FullName, ot.FullName);
                testpurpose.Program obj2 = oh.Unwrap() as testpurpose.Program;
                obj2.sayhi();//工作得很正常

                object obj3 = oa.CreateInstance(ot.FullName);
                testpurpose.Program obj4 = obj3 as testpurpose.Program;//没有工作好。obj4为空。obj3是testpurpose.Program对象
                obj4.sayhi();//抛出nullexecption
                System.Console.ReadKey();

            }

        }
    }

     

    被测程序集如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace testpurpose
    {
        public class Program
        {         
        
            public void sayhi()
            {
                System.Console.WriteLine("say hi");
            }
           
            public static void sayhello()
            {
               
                System.Console.WriteLine("say hello from static");
            }
            static void Main(string[] args)
            {
               
                System.Console.WriteLine("say hello from main.");
            }
        }
    }


    Johnson Dai
    2011年1月18日 4:11

答案

  • 已查出原因。

    在reference里面加载的exe和loadfrom加载的exe算两个不同的程序集。(尽管代码完全一致)。

    要消除这个问题可以把loadfrom里面的路径去掉。

                Assembly oa = Assembly.Load("testpurpose");
    这样找到的是同一个程序集。就可以随便转换了。

    结贴。


    Johnson Dai
    • 已标记为答案 JohnsonDai 2011年1月18日 7:47
    2011年1月18日 7:47

全部回复

  • 已查:

                object obj3 = Activator.CreateInstance(ot);
                testpurpose.Program obj4 = obj3 as testpurpose.Program;//无法完成 转换
                obj4.sayhi();

       该语句同样出错。

    怀疑:activator.createinstance()返回的objecthandler 经过unwrap()得到的object和activator.createinstance()直接返回的对象不一样!

    问题是为啥呢?


    Johnson Dai
    2011年1月18日 5:40
  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.Runtime.Remoting;
    using testpurpose;

    namespace _99testexe
    {
        class Programa
        {
            static void Main(string[] args)
            {
                Assembly oa = Assembly.LoadFrom(@"D:\Projects\CsharpCore\testpurpose\bin\Debug\testpurpose.exe");

                Type ot = oa.GetTypes()[0];
                object obj1 = oa.CreateInstance(ot.FullName);

                foreach (MethodInfo om in ot.GetMethods())

                    if (om.Name == "sayhi")
                        om.Invoke(obj1, null);

                ObjectHandle oh = Activator.CreateInstance(oa.FullName, ot.FullName);
                testpurpose.Program obj2 = oh.Unwrap() as testpurpose.Program;
                obj2.sayhi();
              
                object obj3=AppDomain.CurrentDomain.CreateInstanceAndUnwrap(oa.FullName, ot.FullName);
                testpurpose.Program obj4 = obj3 as testpurpose.Program;
                obj4.sayhi();

                object obj5 = AppDomain.CurrentDomain.CreateInstance(oa.FullName, ot.FullName);
                testpurpose.Program obj6 = oh.Unwrap() as testpurpose.Program;
                obj6.sayhi();

                object obj7 = oa.CreateInstance(ot.FullName);
               
                testpurpose.Program obj8 = obj7 as testpurpose.Program;
                obj8.sayhi();
               //except this not working, above all works well. So,what happened to activator.createinstance() returned object?? (assembly.createinstance is calling activator.createinstance. so ignore it.
                System.Console.ReadKey();

            }

        }
    }


    Johnson Dai
    2011年1月18日 6:27
  • 已查出原因。

    在reference里面加载的exe和loadfrom加载的exe算两个不同的程序集。(尽管代码完全一致)。

    要消除这个问题可以把loadfrom里面的路径去掉。

                Assembly oa = Assembly.Load("testpurpose");
    这样找到的是同一个程序集。就可以随便转换了。

    结贴。


    Johnson Dai
    • 已标记为答案 JohnsonDai 2011年1月18日 7:47
    2011年1月18日 7:47