Ошибка приведения объекта, загруженного через createInstance - PullRequest
0 голосов
/ 15 ноября 2011

У меня есть сборка, которая содержит класс RD_ToBeProcessed, который наследуется от 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: Невозможно привести объект к интерфейсу, он реализует , но я не знаю, как его разрешить.

Выдается ошибка:

Невозможно привести объект типа 'myNameSpace.RD_ToBeProcessed 'для ввода' myNameSpace.ToBeProcessed '.

Принятый ответ показал, что проблема заключалась в 2 разных версиях базовой сборки.Но я использовал ILSpy и оба библиотеки ToBeProcessed в каталоге приложения и тот же каталог, что и отчет RD_ToBeProcessed:

ToBeProcessed, версия = 1.0.4336.31676, Culture = нейтральный, PublicKeyToken = null

Так что я не уверен, что делаю не так.Должен ли я изменить ToBeProcessed на интерфейс (ItoBeProcessed), который используется в приложении и плагине?Тогда есть отдельная сборка, которая содержит базовый класс ToBeProcessed, на который приложение вообще не будет ссылаться (только плагин by)?

РЕДАКТИРОВАТЬ: проблема была решена с помощью интерфейсного класса.Я до сих пор не знаю, что пошло не так, но ответ Кола показал, что в теории это должно было работать правильно, как было.

Ответы [ 3 ]

1 голос
/ 15 ноября 2011

Следующее решение компилируется и запускается без ошибок:

Сборка № 1: ToBeProcessed

Скомпилировано в DLL, которая копируется в c:\project и c:\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
1 голос
/ 15 ноября 2011

некоторые люди спрашивали его, прежде чем посмотреть на этот вопрос в stackoverflow Как получить статическое свойство с помощью Reflection

0 голосов
/ 15 ноября 2011

отметьте это сообщение , оно объясняет размышления примерами.как случай наследования и как использовать type.GetMethods (BindingFlags.LookupAll), чтобы получить все методы.

...