XmlSerializer:“类型’类型’可能不会在此上下文中使用”

我试图弄清楚如何使用XmlSerializer序列化任何类,而不使用XmlInclude属性。 一般工作,但使用以下代码我得到一个例外:

using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Xml.Serialization; namespace Test { public class ReactObject { } public class ReactListObject : ReactObject { } public class ReactList : ReactObject, ICollection, IList { public ReactList() { } public virtual void AddRange(IEnumerable values) { } [XmlArray(ElementName = "Items", IsNullable = false)] public T[] Items { get { lock (SyncRoot) { return (ItemsList.ToArray()); } } set { lock (SyncRoot) { ItemsList = new List(value); } } } protected List ItemsList = new List(); public bool IsSynchronized { get { return (true); } } public object SyncRoot { get { return (mRootObject); } } private object mRootObject = new object(); public void CopyTo(Array array, int index) { CopyTo(array, index); } [XmlIgnore()] public T this[int index] { get { return (ItemsList[index]); } set { ItemsList[index] = value; } } public int IndexOf(T item) { return (ItemsList.IndexOf(item)); } public virtual void Insert(int index, T item) { } public virtual void RemoveAt(int index) { } public int Count { get { lock (SyncRoot) { return (ItemsList.Count); } } } public bool IsReadOnly { get { return (false); } } public virtual void Add(T item) { ItemsList.Add(item); } public void Clear() { } public bool Contains(T item) { return (false); } public virtual void CopyTo(T[] array, int arrayIndex) { } public virtual bool Remove(T item) { return (false); } public IEnumerator GetEnumerator() { return (ItemsList.GetEnumerator()); } IEnumerator IEnumerable.GetEnumerator() { return (ItemsList.GetEnumerator()); } } [XmlInclude(typeof(B))] public class A : ReactListObject { public int AValue = 1; } public class B : A { public int BValue = 2; } public class AList : ReactList { } static class Program { [STAThread] static void Main() { // NOT good serializer for the type AList XmlSerializer ser1 = new XmlSerializer(typeof(ReactObject), new Type[] { typeof(A), typeof(B), typeof(ReactList), typeof(AList) }); // Good serializer for the type AList XmlSerializer ser2 = new XmlSerializer(typeof(ReactList), new Type[] { typeof(A), typeof(B), typeof(AList) }); AList list = new AList(); list.Add(new A()); list.Add(new B()); using (FileStream mStream = new FileStream("C:\\Test.xml", FileMode.Create)) { ser2.Serialize(mStream, list); } using (FileStream mStream = new FileStream("C:\\Test.xml", FileMode.Create)) { ser1.Serialize(mStream, list); } } } } 

exception抛出是

Test.AList类型可能不会在此上下文中使用


这是类图,以帮助代码读取

Da Develop


我想对我正在努力实现的目标花更多的话:我想最小化XML序列化器实例的创建(实际上每个序列化类型都有自己的序列化器;应用程序每次都会重新创建唯一存在的序列化器不包含的类型应序列化。(*)

看来,恕我直言,

  • 可以使用ReactObject类型的序列化程序序列化任何ReactObject (和派生类型),直到在派生层次结构中引入generics类。 额外类型的序列化器应涵盖所有预期类型。
  • 在从基于ReactObjectgenerics类派生的类型的情况下,该类型不能使用类型为ReactObject的序列化程序进行序列化,而是使用generics类型的序列化程序。

这可能是一个问题,因为当我需要反序列化时,我必须知道序列化对象的类型。 相反,反序列化“非generics” ReactObject类型足以使用ReactObject类型的公共序列化程序 ,而不知道序列化对象的确切类型。

(*)实际上我不知道这个目标会带来明显的改善。 核心问题是“ 对于所有(包含的)类型,还是每种类型的串行器组件,它是否更好?

ReactListObject是否inheritance自ReactObjectser1被实例化以序列化ReactObject类型,但是从您的代码示例中我只能告诉该listReactListObject类型。

序列化方面很简单 – 在获取序列化程序时不使用typeof(ReactObject),而是使用list.GetType(),它将返回AList而不是ReactObject并创建正确的序列化程序。 如果您担心实例化过多的序列化程序,您可以始终将它们保存在按类型键入的字典中。

反序列化更难,因为你必须首先知道对象的类型 – 如果你不能让调用者告诉你期望什么类型,你需要在尝试反序列化之前读取数据以确定类型。

首先不应该是这样的:

 //[XmlInclude(typeof(B))] [Serializable] public class A : ReactListObject { public int AValue = 1; } [XmlInclude(typeof(A))] public class B : A { public int BValue = 2; }