简体   繁体   中英

Why can't I serialize readonly fields with XmlSerializer?

XmlSerializer do not serialize readonly fields, readonly properties (only with getter ), private fields etc. In addition it will not serialize the object if the class does not have a parameterless constructor. My questions:

  1. AFAIK these problems arise because private (and readonly) fields can not be accessed (and changed) while deserializing. But what if I will not deserialize? Don't I have an option for this?

  2. Because of the same reason (deserialization concerns), it does not serialize the object if the class does not have a parameterless constructor. But when I add a private parameterless constructor it works fine. How?

  3. I do not like to add a parameterless constructor to every class, and make all fields public and non-readonly just to be able to serialize it. For now I am throwing an exception in the private parameterless constructor to prevent the usage. Is there an attribute for constructors which tells the compiler that only authorized calls can be made to that constructor? If not at least I would like to mark it with an attribute which throws the exception if it is called.

That's quite a good question, and I'll try my best to answer:

  1. I believe the reason for the setter as well as the getter is that it's generally assumed if you've only got a getter, then it implies it's not an instance property, it's something that is derived. That would imply if you were to deserialize it (I know you're not doing this) then you could derive this value by setting all the other fields, and therefore serialization doesn't need to care about it.

  2. The reason the parameterless constructor is required is because the type will be created using Reflection. Probably through a call like Activator.CreateInstace(type) . This requires a parameterless constructor for the instance to be created, although it probably doesn't matter if it's public or private.

    The reason the instance is required is so the fields on it can then be populated with the data retrieved from the XML.

  3. You'll need this constructor, however you could add the ObsoleteAttribute to ensure that it's not called manually, or do as you're doing and make it private.

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

One way of working around some of these issues may be to implement the IXmlSerializable interface manually, then you have a finer control over serialization but will still need that parameterless constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM