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

Luc*_*uca 5 c# xml-serialization

我试图弄清楚如何使用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<T> : ReactObject, ICollection, IList<T>
    {
        public ReactList() { }

        public virtual void AddRange(IEnumerable<T> values) { }

        [XmlArray(ElementName = "Items", IsNullable = false)]
        public T[] Items
        {
            get { lock (SyncRoot) { return (ItemsList.ToArray()); } }
            set { lock (SyncRoot) { ItemsList = new List<T>(value); } }
        }

        protected List<T> ItemsList = new List<T>();

        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<T> 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<A>
    {

    }

    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<A>), typeof(AList) });
            // Good serializer for the type AList
            XmlSerializer ser2 = new XmlSerializer(typeof(ReactList<A>), 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

异常抛出是

在这种情况下不能使用 Test.AList 类型


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

开发

我想多谈一下我要实现的目标:我想尽量减少 XML 序列化程序实例的创建(实际上每个序列化类型都有自己的序列化程序;应用程序每次都会重新创建唯一存在的序列化程序未包含的类型应被序列化。(*)

看来,恕我直言,

  • 可以使用类型为ReactObject的序列化器序列化任何ReactObject(和派生类型),直到在派生层次结构中引入泛型类。序列化器的额外类型应涵盖所有预期类型。
  • 在一种类型的衍生自的情况下通用类基于ReactObject,类型不能与类型的串行化序列ReactObject,但与一般类型的串行化。

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

(*) 其实我不知道这个目标会带来合理的改进。核心问题是“对于所有(包含的)类型使用单个序列化器程序集更好,还是为每个类型使用一个序列化器程序集更好?