C# 如何序列化&;反序列化从运行时之前未知的抽象类派生的类型?

C# 如何序列化&;反序列化从运行时之前未知的抽象类派生的类型?,c#,serialization,xml-serialization,abstract-class,abstract,C#,Serialization,Xml Serialization,Abstract Class,Abstract,我在XML序列化和反序列化一个类时遇到了问题,该类包含实现基本抽象类的具体类的实例集合 我的解决方案是这样组织的: 包含名为Base的抽象类的类库项目 另一个类库项目用作插件,其中包含一个名为派生的具体类,该类实现了Base。我将有不止一个这样的项目,因为我将把它们作为插件加载到主项目中 一个应用程序,它是主项目。它知道使用第一个项目作为引用,并加载插件程序集,这些插件程序集导出一个具体的类,该类在运行时实现Base,就像第二个项目一样。启动时,在使用反射加载程序集之后,它将加载实现Base的类

我在XML序列化和反序列化一个类时遇到了问题,该类包含实现基本抽象类的具体类的实例集合

我的解决方案是这样组织的:

  • 包含名为Base的抽象类的类库项目
  • 另一个类库项目用作插件,其中包含一个名为派生的具体类,该类实现了Base。我将有不止一个这样的项目,因为我将把它们作为插件加载到主项目中
  • 一个应用程序,它是主项目。它知道使用第一个项目作为引用,并加载插件程序集,这些插件程序集导出一个具体的类,该类在运行时实现Base,就像第二个项目一样。启动时,在使用反射加载程序集之后,它将加载实现Base的类的序列化实例,并在关闭时反序列化它们
  • 以下是我的课程示例:

    假设我在一个项目中有一个抽象类,叫做BaseClassProj:

    public abstract class Base
    {
        public int  BaseProp { get; set; }
    }
    
    我有另一个项目,DerivedClassProj,在该项目中我实现了基本抽象类,并添加了一些属性:

    public class Derived : Base
    {
        public string DerivedProp { get; set; }
    }
    
    还有一个第三个也是主要的项目,其中我有一个类,它包含一个字典,键类型是类型的名称,它必须是基类的某个派生类,值是给定类型的实例的集合ObservableDictionary是XML可序列化的,实现是。例如:

    public class Manager
    {
        public ObservableDictionary<string, ObservableCollection<Base>> Instances { get; set; }
    }
    
    重载XmlSerializer构造函数,以便序列化和反序列化主类

    当我尝试序列化Manager类时,引发了InvalidOperationException:

    派生的类型(或实现Base的任何其他具体类)不是预期的类型。使用XmlInclude或SoapInclude属性指定静态未知的类型

    正如我所说的,我不知道在预先序列化和反序列化时我正在处理的类型,因为我在运行时使用反射加载它们,因此我不能在基类上使用XmlInclude属性。在序列化或反序列化之前,我知道的唯一一件事是,Base可以从我正在处理的类型中赋值

    那么,问题是什么呢?我使用typeof(Base)作为主类型初始化了XmlSerializer,并使用了一个类型数组,其中Base是可分配的


    提前谢谢!我一直在努力找出满足我的需求的解决方案,并在互联网上搜索了一整天。

    也许这会有所帮助。遗憾的是,JSON和XML不是一回事,他似乎没有像我一样的问题。你可以在这里做一些事情:,或者在这里。序列化对象而不是类型。对象的GetType()方法将很有用。显然,我序列化对象,而不是类型。问题是,即使我尝试序列化一个对象,该对象属于从基抽象类派生的类的类型,它仍然表示不需要这种类型,我应该使用XmlInclude,但我不能,因为在运行时加载它们之前,我不知道要处理的类型,就在我尝试反序列化此类对象的列表之前。这可能会有所帮助。遗憾的是,JSON和XML不是一回事,而且他似乎没有像我一样的问题。你可以像这里所做的那样:,或者在这里。序列化对象而不是类型。对象的GetType()方法将很有用。显然,我序列化对象,而不是类型。问题是,即使我尝试序列化一个对象,该对象属于从基抽象类派生的类的类型,它仍然表示不需要这种类型,我应该使用XmlInclude,但我不能,因为在运行时加载它们之前,我不知道要处理的类型,就在我尝试反序列化这种类型的对象列表之前。
    // Type = Base, extraTypes = { Derived, [another derived class, ...] }
    public XmlSerializer(Type type, Type[] extraTypes){..}