XmlSerializer 测试 2

TOC

集合

using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var f = new XmlSerializer(typeof(TestClass));
            using (var sw = new StringWriter())
            {
                f.Serialize(sw, new TestClass());
                using (var sr = new StringReader(sw.ToString()))
                {
                    var bt = (TestClass) f.Deserialize(sr);
                    Console.WriteLine(bt.ListIdentical());
                }
            }
        }
    }

    public class TestClass
    {
        private List<int> PrivateList;
        public List<int> MyList;

        public bool ListIdentical()
        {
            return PrivateList == MyList;
        }

        public TestClass()
        {
            PrivateList = new List<int>() { 123, 567 };
            MyList = PrivateList;
        }
    }
}

运行结果为 `True` 。实际上,如果把 `MyList` 换成只读属性,只要其值非 null / Nothing,则程序仍可以正常运行。

也就是说,反序列化过程复用了已有的集合实例。

发生变化的类

using System;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var f = new XmlSerializer(typeof(TestClass));
            var f1 = new XmlSerializer(typeof(TestClass1));
            using (var sw = new StringWriter())
            {
                f.Serialize(sw, new TestClass());
                using (var sr = new StringReader(sw.ToString()))
                {
                    var tc1 = (TestClass1) f1.Deserialize(sr);
                    Console.WriteLine("{0}, {1}", tc1.Value1, tc1.Value2);
                }
            }
        }
    }

    public class TestClass
    {
        public int Value1 = 10;
    }

    [XmlType("TestClass")]
    public class TestClass1
    {
        public int Value1 = 20;
        public int Value2 = 30;
    }
}

运行结果为

10, 30

说明反序列化过程中可以自动跳过缺失 XML 元素的属性/字段。

字典

XML 序列化不支持所有实现 IDictionary 接口的类。

可以替代的方法:自定义XML序列化Dictionary<int, string=””>

循环引用

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    class Program
    {
        private static void Main(string[] args)
        {
            var f = new XmlSerializer(typeof(TestClass));
            using (var sw = new StringWriter())
            {
                var tc = new TestClass();
                tc.MyList = new List<MyClass>(){new MyClass(), new MyClass()};
                tc.Ref = tc.MyList[0];
                f.Serialize(sw, tc);
                Console.WriteLine(sw.ToString());
            }
        }
    }

    public class TestClass
    {
        public List<MyClass> MyList;

        public MyClass Ref;
    }

    public class MyClass
    {
        public int Value;
    }
}

运行结果如下

<?xml version="1.0" encoding="utf-16"?>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <MyList>
    <MyClass>
      <Value>0</Value>
    </MyClass>
    <MyClass>
      <Value>0</Value>
    </MyClass>
  </MyList>
  <Ref>
    <Value>0</Value>
  </Ref>
</TestClass>

`XmlSerializer`对循环引用处理的方法为按值展开。要解决这一问题,可以手动实现`IXmlSerializable`,或者使用`DataContractSerializer`。具体的处理方法可以参考:
WCF 第六章 序列化与编码 保留引用和循环引用

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

ERROR: si-captcha.php plugin: GD image support not detected in PHP!

Contact your web host and ask them to enable GD image support for PHP.

ERROR: si-captcha.php plugin: imagepng function not detected in PHP!

Contact your web host and ask them to enable imagepng for PHP.

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

Content is available under CC BY-SA 3.0 unless otherwise noted.