C# 使用XML序列化对象(二)

C# 使用XML序列化对象(一)中描述了使用XML序列化对象的最简单的实现。

现在我们来看看稍微复杂一点的情况:

现有两个类:A和B,B是A的派生类,如下所示:

    public class A
    {
        public int a
        {
            get;
            set;
        }
    }

    public class B : A
    {
        public int b
        {
            get;
            set;
        }
    }

如果使用C# 使用XML序列化对象(一)中的方法来直接序列化类B的实例,会抛下面的异常:

"不应是类型 B。使用 XmlInclude 或 SoapInclude 特性静态指定非已知的类型。"

解决办法一:

在类A上使用XmlInclude特性标记类B,如下所示:

    [XmlInclude(typeof(B))]
    public class A
    {
        public int a
        {
            get;
            set;
        }
    }

    public class B : A
    {
        public int b
        {
            get;
            set;
        }
    }

再使用如下代码序列化类B的实例:

    B objB = new B
    {
        a = 1,
        b = 2
    };

    string xml = XmlSerialize(objB);

    var obj = XmlDeserialize<B>(txt.Text);

输出的XML如下所示:

<?xml version="1.0" encoding="utf-16"?>
<B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <a>1</a>
  <b>2</b>
</B>

当然,你也可以通过基类来序列化派生类,如下:

    A objA = new B
    {
        a = 1,
        b = 2
    };

    string xml = XmlSerialize(objA);

    var obj = XmlDeserialize<A>(txt.Text);

这种方式输出的XML如下所示:

<?xml version="1.0" encoding="utf-16"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="B">
  <a>1</a>
  <b>2</b>
</A>

我们可以看到这里输出的XML里的标签名称是基类的名称,但是在属性中使用xsi:type="B"指定了对象的类型是派生类B。

还有另外一种方式可以不用在基类A上使用XmlInclude特性标记派生类B,如下:

    public class A
    {
        public int a
        {
            get;
            set;
        }
    }

    public class B : A
    {
        public int b
        {
            get;
            set;
        }
    }

    A objA = new B
    {
        a = 1,
        b = 2
    };

    string xml = null;
    XmlSerializer xs = new XmlSerializer(typeof(A), new Type[] { typeof(B) });

    using (TextWriter tw = new StringWriter())
    {
        xs.Serialize(tw, objA);
        xml = tw.ToString();
    }

    object obj = null;

    using (TextReader tr = new StringReader(xml))
    {
        obj = xs.Deserialize(tr);
    }
原文地址:https://www.cnblogs.com/action98/p/3491654.html