【问题标题】:Why can't I serialize readonly fields with XmlSerializer?为什么我不能用 XmlSerializer 序列化只读字段?
【发布时间】:2014-08-28 21:02:52
【问题描述】:

XmlSerializer 不会序列化只读字段、只读属性(仅限getter)、私有字段等。此外,如果类没有无参数构造函数,它也不会序列化对象。我的问题:

  1. AFAIK 出现这些问题是因为在反序列化时无法访问(和更改)私有(和只读)字段。但是如果我不反序列化怎么办?我没有这个选项吗?

  2. 由于同样的原因(反序列化问题),如果类没有无参数构造函数,它不会序列化对象。但是当我添加一个私有无参数构造函数时,它工作正常。怎么样?

  3. 我不喜欢为每个类添加一个无参数的构造函数,并且为了能够序列化它而将所有字段设为公共和非只读。现在我在私有无参数构造函数中抛出异常以防止使用。构造函数是否有一个属性告诉编译器只能对该构造函数进行授权调用?如果不是,至少我想用一个属性标记它,如果它被调用就会抛出异常。

【问题讨论】:

  • 1,2) 我认为原因是点 od 序列化是稍后的反序列化。这就像你想在你的旅行行李里放一些东西,即使你知道机场安检不会把它还给你。 3)你所说的“授权”电话是什么意思?来自类本身的调用?
  • @KamilT 通过“授权调用”我的意思是,例如,仅允许(或根本不允许)来自特定方法的调用。对于这个问题Obsolote 解决了我的问题。

标签: c# attributes xml-serialization


【解决方案1】:

这是一个很好的问题,我会尽力回答:

  1. 我相信 setter 和 getter 的原因是,通常假设您只有一个 getter,那么这意味着它不是实例属性,而是派生的东西。这意味着如果你要反序列化它(我知道你没有这样做),那么你可以通过设置所有其他字段来派生这个值,因此序列化不需要关心它。

    李>
  2. 需要无参数构造函数的原因是因为该类型将使用反射创建。可能是通过像Activator.CreateInstace(type) 这样的电话。这需要一个无参数的构造函数来创建实例,尽管它是公共的还是私有的可能并不重要。

    需要该实例的原因是,然后可以使用从 XML 检索到的数据填充其上的字段。

  3. 您将需要这个构造函数,但是您可以添加 ObsoleteAttribute 以确保它不会被手动调用,或者按照您的操作将其设为私有。

    [Obsolete(true)]
    public Foo() 
    {
    
    }
    

解决其中一些问题的一种方法可能是手动实现IXmlSerializable 接口,然后您可以更好地控制序列化,但仍需要无参数构造函数。

【讨论】:

  • 关于 nr 3 - Obsolete(true) 不会阻止对函数的所有调用吗?即使是“授权”(仍在等待OP的定义)方式?
  • @KamilT:如果他只是在序列化之前添加它,它应该可以正常工作,因为它会产生编译错误而不是运行时错误。由于在代码中从来没有直接调用,因此在构建时应该不是问题。
  • 感谢您的清晰解释。它为我清除了大部分问号。
  • 如果您需要使用 xmlserialization,如何将属性设为只读?除了使用包装类之外,我看不到任何其他方法。
  • 感谢伊恩的解释。这真的很重要!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 2013-07-09
  • 2011-05-26
相关资源
最近更新 更多