Serialize List<> of classes declared with inter

2019-06-23 02:51发布

问题:

I'm trying to add XML serialization to a fairly trivial class structure in C#. Essentially, there's a single instance of a root class (call it AClass), which holds a List of several instances of some other class (call it AnotherClass):

[XmlRoot("RootNode")]
public class AClass {
    [XmlElement("ListNode")]
    internal List otherObjects { get; set; }
}

public class AnotherClass {
    [XmlAttribute("Name")]
    internal string name { get; set; }
}

When serializing, I'd like for both these classes to be serialized together - that is, if I serialize AClass, its list of AnotherClass gets serialized as well (see this question).

I have this mostly working, but the problem is that during serialization, XmlSerializer only seems to want to deal with public properties of the class - it doesn't serialize AnotherClass at all if the list is declared internal.

I tried making the assembly's internals visible to the serializer:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.Xml")]

That didn't seem to do anything. Is there a way I can get XmlSerializer to recursively serialize lists of objects that are declared internal?

回答1:

You're on the right track... except that the actual serialization is not performed by System.Xml, but by a dynamically generated assembly. You can't predict the name of that assembly (it's randomly generated), so you can't use it in the InternalsVisibleTo attribute.

The only solution is to pre-generate the XML serialization assembly. You can do that using the XML Serializer Generator Tool (Sgen.exe). The name of the generated assembly will be "YourAssembly.XmlSerializers" ; that's the name you have to use in the InternalsVisibleTo attribute.



回答2:

The idea of adding the InternalsVisibleTo attribute is a good one, but I think that the problem is that the Xml serialization code only looks for the public types in the assembly.
To my knowledge there is no way to make XmlSerializer serialize or deserialize internal types, and you will have to either declare the types as public or write your own serialization code.
Moreover, the XmlSerializer class documentation explicitly states that only public properties of the object will be serialized: "XML serialization is the process of converting an object's public properties and fields to a serial format (in this case, XML) for storage or transport", so it really looks like it's a design decision.