XmlSerializer 和 IEnumerable:可以进行序列化,无需无参数构造函数:Bug?

2024-02-27

在我们的项目中,我们广泛使用 XmlSerializer。偶然我发现了一个没有无参数构造函数的类。我认为这一定会破坏序列化过程,但事实并非如此。

通过调查这个问题,我发现 XmlSerializer 在序列化/反序列化时表现得很奇怪IE可枚举:

  • 可枚举的所有元素均已序列化
  • 该类需要实现添加(对象) method
  • 它忽略此类中可能存在的所有其他属性。
  • 它使用此属性调用 getter 并重用返回的实例进行序列化(这允许 XmlSerializer 无需无参数构造函数即可工作)。

请看下面的示例。有趣的部分是 ODD1、ODD2。请注意,good5 和 good6 是假的,而我期望它们是真的。

这种行为有原因吗?

在手动实现 IXmlSerialized 时,是否可以让 XmlSerializer 重用属性返回的实例进行反序列化?

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

namespace Test
{
    public static class Program
    {
        public static void Main()
        {
            HostingClass host = new HostingClass();

            host.AutomaticSerialization.StringProperty = "AUTO";
            host.SelfImplementedSerialization.StringProperty = "SELF";

            bool good1 = host.AutomaticSerialization.FromConstructor == "PARAMETER";
            bool good2 = host.SelfImplementedSerialization.FromConstructor == "PARAMETER";
            bool good3 = host.AutomaticSerialization.StringProperty == "AUTO";
            bool good4 = host.SelfImplementedSerialization.StringProperty == "SELF";

            XmlSerializer serializer = new XmlSerializer(typeof(HostingClass));

            using (StringWriter sw = new StringWriter())
            {
                serializer.Serialize(sw, host);

                using (StringReader sr = new StringReader(sw.ToString()))
                {
                    host = (HostingClass)serializer.Deserialize(sr);
                }
            }

            bool good5 = host.AutomaticSerialization.FromConstructor == null; //is false
            bool good6 = host.AutomaticSerialization.StringProperty == "AUTO"; //is false

            bool good7 = host.SelfImplementedSerialization.FromConstructor == null;
            bool good8 = host.SelfImplementedSerialization.StringProperty == "SELF";

        }
    }

    public class HostingClass
    {
        private SelfImplementedSerialization _selfImplementedSerialization;
        public SelfImplementedSerialization SelfImplementedSerialization
        {
            get
            {
                return _selfImplementedSerialization
                       ?? (_selfImplementedSerialization = new SelfImplementedSerialization("PARAMETER"));
            }
            set { _selfImplementedSerialization = value; }
        }

        private AutomaticSerialization _automaticSerialization;
        public AutomaticSerialization AutomaticSerialization
        {
            get
            {
                return _automaticSerialization
                       ?? (_automaticSerialization = new AutomaticSerialization("PARAMETER")); //the returned object is used while deserializing
            }
            set { _automaticSerialization = value; }
        }
    }

    public class SelfImplementedSerialization : IXmlSerializable, IEnumerable<int>
    {
        public SelfImplementedSerialization() { }
        public SelfImplementedSerialization(string parameter)
        {
            FromConstructor = parameter;
        }

        public string StringProperty { get; set; }
        [XmlIgnore]
        public string FromConstructor { get; set; }

        public void ReadXml(XmlReader reader)
        {
            reader.ReadStartElement();
            StringProperty = reader.ReadElementString("StringProperty");
            reader.ReadEndElement();
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteElementString("StringProperty", StringProperty);
        }

        public IEnumerator<int> GetEnumerator()
        {
            yield return 1;
            yield return 2;
        }

        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
        public XmlSchema GetSchema() { return null; }
    }


    public class AutomaticSerialization : IEnumerable<int>
    {
        //ODD1: Serialization possible w/o public parameterless constructor
        //public AutomaticSerialization() {} 
        public AutomaticSerialization(string parameter)
        {
            FromConstructor = parameter;
        }

        //ODD2: Element not serialized, only the IEnumerable Interface is serialized
        [XmlElement("SP")]
        public string StringProperty { get; set; }
        [XmlIgnore]
        public string FromConstructor { get; set; }

        public IEnumerator<int> GetEnumerator()
        {
            yield return 1;
            yield return 2;
        }

        public void Add(object o)
        {
            //requirement of XmlSerializer when serializing IEnumerables
        }

        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
    }
}

出现这种行为的原因是它一直都是这样工作的。

From XmlSerializer 类 http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx:

Note

The XmlSerializer给予特别的 对实施类的处理IEnumerable or ICollection。一类 实现IEnumerable必须 实现一个公共 Add 方法 采用单个参数。添加 方法的参数必须相同 类型为从返回的Current返回值的属性GetEnumerator,或该类型之一 基地。一个实现的类ICollection(例如CollectionBase) 此外IEnumerable必须有一个 公共项目索引属性(索引器 在 C# 中),它接受一个整数,并且它 必须具有公共 Count 属性 类型整数。添加参数 方法必须与 is 类型相同 从 Item 属性返回,或者 该类型的基地之一。上课用 实施ICollection,值到 被序列化是从检索 索引 Item 属性,而不是通过调用GetEnumerator.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

XmlSerializer 和 IEnumerable:可以进行序列化,无需无参数构造函数:Bug? 的相关文章

随机推荐

  • 为什么 scikit-learn 的最近邻似乎没有返回正确的余弦相似距离?

    我正在尝试使用 scikit 的最近邻实现从随机值矩阵中查找与给定列向量最接近的列向量 该代码应该找到第 21 列的最近邻居 然后检查这些邻居与第 21 列的实际余弦相似度 from sklearn neighbors import Nea
  • T-SQL 根据列值的变化递增计数器

    我有如下示例表 该表按未显示的另一列排序 我需要根据值列中的任何变化来增加计数器列值 请参阅下面的示例 如何在 T SQL SQL Server 2014 中完成此操作 ID Value 1 3 2 3 3 2 4 2 5 2 6 3 7
  • 数据触发器未触发

    我有以下 xaml
  • 如何在不同平台有不同的Header? [复制]

    这个问题在这里已经有答案了 我对 C 还很陌生 我有一个必须在 Linux 和 Windows 中构建的文件 我想知道是否有一种方法可以在 Windows 和 Linux 的同一个文件中拥有不同的 include 列表 但不知何故我告诉它这
  • 如何在一个布局中实现多个recyclerview?

    我想创建一个窗格 其中有两个RecyclerViews 假设 MyItems AllItems 我创建了垂直LinearLayout 其中有TextView作为标题和RecyclerView 像这样的东西
  • 在 Visual Studio Webtest 中插入 120 秒等待

    我想在两个 Web 请求的执行之间添加 120 秒的延迟 我尝试过使用思考时间 但它不会暂停执行 120 秒 谁能告诉我如何添加等待以暂停执行 120 秒 在执行 2 个 Web 请求之后 然后继续执行下一个请求 我正在使用 Visual
  • ImportError:无法导入名称 celery

    我正在尝试使用 Celery Redis Flask 运行一些后台作业 我的应用程序结构是 myapp celery worker py manage py myapp init py app py bot init py tasks py
  • 使无边框窗口具有较暗较大的阴影

    当无边框窗口中的窗口变为活动状态时 如何创建更暗和更大的阴影 我对 NSWindow 进行了子类化 我的窗口成为主窗口和关键窗口 但这没有帮助 阴影仍然很小 那么也许有人知道如何解决这个问题 我也尝试过使阴影无效 但这也没有帮助 NSWin
  • 使用 SQL 中的结果计算每天的总数

    我的订单表中有 50 行 条目 我有一个列 当订单被认领时保存 名为claimed at 该字段中的日期格式如下 2011 10 03 07 07 33 格式为 yy mm dd 时间 我还有一个专栏叫price this price是他们
  • Loopback.io 的 ACL 问题

    我目前正在评估用于开发新项目的 API 部分的 Loopback io 但在设置正确的 ACL 条目时遇到问题 我希望完成的是给定一个身份验证令牌 GET 端点应该只返回用户拥有的对象 例如 对 Shows access token xxx
  • 什么是“SQLiteDatabase 创建且从未关闭”错误?

    我已经在我的适配器类中关闭了数据库 那么为什么这个错误显示在 logcat 上 但我的应用程序不强制关闭 但只有错误显示在 log cat 上 我应该关闭数据库以忽略此错误 我的错误是 下面 我离开哪个类来关闭数据库 我从此链接获取帮助ht
  • C#,求一个数的最大素因数

    我是编程新手 正在练习我的 C 编程技能 我的应用程序旨在查找用户输入的数字的最大素因数 但我的应用程序没有返回正确的答案 我真的不知道问题出在哪里 你能帮我么 using System using System Collections G
  • 从 Action Script 到 C# 的 Rijndael 加密

    我正在尝试在 Action Script 和 C 之间共享加密 我的任务是在 C 中解密以下消息 f1ca22a365ba54c005c3eb599d84b19c354d26dcf475ab4be775b991ac97884791017b1
  • UUID 转换为无符号整数

    有没有地方可以将 UUID 压缩 转换 编码 加密为无符号整数 我从 sql 表中读取 UUID 历史记录很难看 我无法更改 我只有一个 unsigned int 来存储它 这是 C 以防产生影响 对此有什么想法吗 谢谢 礼萨 正如其他人所
  • 在两个容器之间共享/tmp

    我在用着docker compose生成两个容器 我想分享 tmp这两个容器之间的目录 但不与主机 tmp如果可能的话 这是因为我正在通过上传一些文件flask to tmp并想要处理这些文件celery flask build comma
  • 撤销 IdentityServer4 中特定会话的访问令牌(参考)

    我在用IdentityServer 4带有参考标记的隐式流程 我自己做了一个实现IPersistedGrantStore https github com IdentityServer IdentityServer4 blob releas
  • SVG使用element来克隆SVG

    是否可以在单独的 svg 中 使用 整个其他 svg 我想使用 d3 生成的地图作为同一页面上的图标 这是我尝试过的 但它不起作用
  • Angualr2 错误:无法设置仅具有 getter 的 # 的属性值

    表格看起来像
  • IntelliJ + JUnit 5(木星)

    My build gradle has testCompile org junit jupiter junit jupiter api 5 0 0 使用标准示例http junit org junit5 docs current user
  • XmlSerializer 和 IEnumerable:可以进行序列化,无需无参数构造函数:Bug?

    在我们的项目中 我们广泛使用 XmlSerializer 偶然我发现了一个没有无参数构造函数的类 我认为这一定会破坏序列化过程 但事实并非如此 通过调查这个问题 我发现 XmlSerializer 在序列化 反序列化时表现得很奇怪IE可枚举