【问题标题】:Error casting object loaded via createInstance错误转换通过 createInstance 加载的对象
【发布时间】:2011-12-29 09:58:09
【问题描述】:

我有一个程序集,其中包含继承自 ToBeProcessed 的类 RD_ToBeProcessed。这些类位于单独的程序集中。

我使用 createInstance 加载一个对象,然后尝试使用以下代码对其进行转换:

    private Type tbpType = null;
    public ToBeProcessed getToBeProcessedObject(string data)
    {
        // The data is passed in so that the fields are populated with the
        // correct data.
        if (tbpType==null){
            Assembly assembly = 
                Assembly.LoadFrom("c:\\project\\RD_ToBeProcessed.dll");
            tbpType = assembly.GetType("myNameSpace.RD_ToBeProcessed");
        }
        Object tbp = Activator.CreateInstance(tbpType,data);
                    // This line throws an error
        return (ToBeProcessed)tbp;
    }

这是重复的问题 .NET: Unable to cast object to interface it implements 但不知道怎么解决。

抛出的错误是

无法将“myNameSpace.RD_ToBeProcessed”类型的对象转换为“myNameSpace.ToBeProcessed”类型。

接受的答案表明问题出在基础程序集的 2 个不同版本上。但我使用了 ILSpy 和应用程序目录中的 ToBeProcessed dll,以及与 RD_ToBeProcessed 报告位于同一目录中的 dll:

待处理,版本=1.0.4336.31676,文化=中性,PublicKeyToken=null

所以我不确定我做错了什么。我应该将 ToBeProcessed 更改为应用程序和插件中使用的接口(ItoBeProcessed)吗?然后有一个单独的程序集来保存基础 ToBeProcessed 类,该类根本不会被应用程序引用(只是 by 插件)?

编辑:问题已通过使用接口类解决。我仍然不知道出了什么问题,但 Kol 的回答表明,理论上这应该可以正常工作。

【问题讨论】:

    标签: c# casting createinstance


    【解决方案1】:

    以下解决方案编译运行无错误:

    程序集 #1:待处理

    编译成DLL,复制到c:\projectc:\project\test。指 System.dll。 ToBeProcessed.cs:

    using System;
    using System.Reflection;
    
    [assembly: AssemblyVersion("1.0.*")]
    
    namespace myNameSpace
    {
      public class ToBeProcessed
      {
        protected string data;
        public ToBeProcessed() { }
        public string Process() { return data.ToUpper(); }
      }
    }
    

    程序集 #2:RD_ToBeProcessed

    编译成DLL,复制到c:\project。指 System.dll 和 ToBeProcessed.dll。 RD_ToBeProcessed.cs:

    using System;
    using System.Reflection;
    
    [assembly: AssemblyVersion("1.0.*")]
    
    namespace myNameSpace
    {
      public class RD_ToBeProcessed : ToBeProcessed
      {
        public RD_ToBeProcessed(string data) { this.data = data; }
      }
    }
    

    程序集 #3:ToBeProcessedTest

    编译成EXE,复制到c:\project\test。指 System.dll 和 ToBeProcessed.dll。 ToBeProcessedTest.cs:

    using System;
    using System.Reflection;
    
    [assembly: AssemblyVersion("1.0.*")]
    
    namespace myNameSpace
    {
      class ToBeProcessedTest
      {
        private Type tbpType = null;
        public ToBeProcessed getToBeProcessedObject(string data)
        {
          if (tbpType == null)
          {
            Assembly assembly = Assembly.LoadFrom("c:\\project\\RD_ToBeProcessed.dll");
            tbpType = assembly.GetType("myNameSpace.RD_ToBeProcessed");
          }
          Object tbp = Activator.CreateInstance(tbpType, data);
          return (ToBeProcessed)tbp;
        }
    
        public static void Main()
        {
          ToBeProcessedTest test = new ToBeProcessedTest();
          ToBeProcessed tbp1 = test.getToBeProcessedObject("myData1");
          Console.WriteLine(tbp1.Process());
          ToBeProcessed tbp2 = test.getToBeProcessedObject("myData2");
          Console.WriteLine(tbp2.Process());
          Console.ReadKey(true);
        }
      }
    }
    

    输出:

    MYDATA1
    MYDATA2
    

    【讨论】:

    • 嗯,毫无疑问,您已经解决了这个问题。非常感动。我认为可能导致问题的唯一一件事是,在创建 RD_ToBeProcessed 实例之前,我在 ToBeProcessed 中调用了一些静态方法。也许这会导致问题??
    • 直觉上,没有。可以肯定的是,我通过将静态 SetParentheses 方法添加到 ToBeProcessed 并在创建 tbp1 和 tbp2 之前调用它来测试这一点。代码编译运行没有问题。
    • 尽管我只是通过其他方式解决了我的问题,但我不得不接受你的回答,因为你证明它应该按照原来的方式工作。
    【解决方案2】:

    之前有人问过 看看stackoverflow中的这个问题How to get a Static property with Reflection

    【讨论】:

      【解决方案3】:

      查看post,它通过示例解释了反射。比如继承的情况以及如何使用type.GetMethods (BindingFlags.LookupAll)获取所有方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-21
        • 1970-01-01
        • 2014-02-05
        • 1970-01-01
        相关资源
        最近更新 更多